【HDU 1275 && HDU 1677】 两题类似,经典 DP。
2012-11-30 18:34
337 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1257
题目链接:
1257
解题思路:
一开始一直纠结在求最小下降的次数(从大减少到最小的的为一次)。 想了很久才恍然大悟,这题可以转换成求最长非降子序列。贪心思想。
1677
题目大意:给你n个宽为w,高为h的洋娃娃,小的洋娃娃能装到大的洋娃娃里面。问你尽可能装完后剩下的洋娃娃数。
解题思路:
这题和上一题思想类似,先排个序,注意排序的时候w从大到小排,当w相等时h从小到大排,这么排的原因是w或者h相同的不能被装下(后面的dp会让你清楚为什么这么排)。接下来如果和上题一样用直接用贪心做的话,TLE,囧。
这题要换种做法,用dp。将排序后的h存入dp[0~n-1]中,再从0开始对这个序列进行遍历。定义一个max_len最长递增序列长度。如果第i个h大于前面存的,max_len加1,并存入dp[max_len]的最后一个。如果小于第j个(j属于(0~max_len-1)),则将第dp[i]替换第dp[j]。以此类推,动态的更新存储求得的max_len就是最大的了。
题目链接:
1257
解题思路:
一开始一直纠结在求最小下降的次数(从大减少到最小的的为一次)。 想了很久才恍然大悟,这题可以转换成求最长非降子序列。贪心思想。
http://acm.hdu.edu.cn/showproblem.php?pid=1257#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> using namespace std; const int maxn=150000; int max_len[maxn]; int f[maxn]; int main() { int n, flag; while(cin >> n) { for(int i=1; i<=n; i++) cin >> f[i]; int Max=-1; for(int i=1; i<=n; i++) { max_len[i]=1; for(int j=1; j<i; j++) { if( f[j]<f[i] && max_len[j]+1>max_len[i]) { max_len[i]=max_len[j]+1; } } if(Max<max_len[i]) { Max=max_len[i]; } } cout << Max <<endl; } return 0; }
1677
题目大意:给你n个宽为w,高为h的洋娃娃,小的洋娃娃能装到大的洋娃娃里面。问你尽可能装完后剩下的洋娃娃数。
解题思路:
这题和上一题思想类似,先排个序,注意排序的时候w从大到小排,当w相等时h从小到大排,这么排的原因是w或者h相同的不能被装下(后面的dp会让你清楚为什么这么排)。接下来如果和上题一样用直接用贪心做的话,TLE,囧。
这题要换种做法,用dp。将排序后的h存入dp[0~n-1]中,再从0开始对这个序列进行遍历。定义一个max_len最长递增序列长度。如果第i个h大于前面存的,max_len加1,并存入dp[max_len]的最后一个。如果小于第j个(j属于(0~max_len-1)),则将第dp[i]替换第dp[j]。以此类推,动态的更新存储求得的max_len就是最大的了。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> using namespace std; const int maxn=20005; int dp[maxn]; struct node { int w, h; }f[maxn]; bool cmp(node A, node B) { if(A.w!=B.w) return A.w>B.w; else return A.h<B.h; } int LIS(int n) { int max_len=0, i, j; for(i=0; i<n; i++) { for(j=0; j<max_len; j++) if(dp[i]<dp[j]) break; if(j==max_len) max_len++; dp[j]=dp[i]; } return max_len; } int main() { int T, n; cin >> T; while(T--) { cin >> n; for(int i=0; i<n; i++) scanf("%d%d",&f[i].w,&f[i].h); sort(f,f+n,cmp); memset(dp,0,sizeof(dp)); for(int i=0; i<n; i++) dp[i]=f[i].h; cout << LIS(n) <<endl; } return 0; }
相关文章推荐
- NYOJ 36 &&HDU 1159 最长公共子序列(经典)
- 类似区间计数的种类并查集两题--HDU 3038 &amp; POJ 1733
- HDU 5348 MZL's endless loop(思想用的是深搜)经典
- hdu1009,FatMouse' Trade,经典贪心算法
- HDU 1102 && POJ 2421 Constructing Roads (经典MST~Prim)
- hdu 2571&hdu 2577(简单经典dp)
- UVA 11368 & POJ 3636 & HDU 1677 Nested Dolls(贪心 + 二分LIS)
- hdu 2732 && poj 2711 Leapin' Lizards(dinic && 拆点建图经典)
- HDU1009 FatMouse' Trade(经典贪心)
- HDU 1250 Hat's Fibonacci (Java大数,类似Fib数,有个坑!!)
- hdu 3572 Task Schedule(最大流&&建图经典&&dinic)
- HDU 1529 && POJ 1275 Cashier Employment
- HDU-1016-Prime Ring Problem( C && 经典DFS题 )
- HDU 1350 & HDU 1960 & POJ 2060 Taxi Cab Scheme【二分图之最小路径覆盖,经典】
- HDU 3488--Tour【最小费用最大流 && 有向环最小权值覆盖 && 经典】
- poj 1275 & hdu 1529 Cashier Employment
- HDU 1677 与1257类似 排序 + 二分
- HDU 3081--【二分图 && 传递闭包 && 完美匹配次数 && 经典】
- HDU 1009 FatMouse' Trade(经典贪心)
- 【HDU 1058 & HDU 3199 类似丑数】 简单DP思想