标签:
参考链接:http://blog.csdn.net/xiaohuan1991/article/details/6956629
(HDU 1257 解题思路一样就不继续讲解)
POJ 1065题意:给你n个木块,分别给出其长度和重量,然后要对这些木块进行加工,如果木块1的长度和重量都不大于木块2,
那么这两个木块可以放在一起加工,从而只用花费1个时间单位。问要如何进行加工从而能够花费最少时间单位。
知识点:
偏序集:若一个集合A为偏序集,那么满足:1、任意一个元素X属于集合,那么这个元素X≤X
2、如果集合内的元素X和Y,X≤Y且Y≤X,那么X=Y
3、如果集合内的元素X,Y,Z,X≤Y且Y≤Z,那么X≤Z
Dilworth定理:对于一个偏序集,其最少链划分数等于其最长反链的长度。
Dilworth定理的对偶定理:对于一个偏序集,其最少反链划分数等于其最长链的长度。
Dilworth定理的证明先留着,后面有空再证。
解法:首先对所有木块按照长度从小到大进行排序,然后问题就转化为了:求最少划分数,能够使得每个划分里面木块的重量是非递减的。
所以当前问题就忽略了长度,只用考虑重量就可以了。
排好序的木块,显然,其重量的集合的大于等于关系就是偏序关系,
比如木块A的重量必然≥A;若A的重量≥B,B≥A,那么A=B;若A≥B,B≥C,那么A≥C。
每个划分里面的木块重量非递减,那么显然划分里两两木块的重量是可以比较的,也就是链。
此时就转换成了求该集合的最少链划分数,也就是最长反链的长度。
反链,也就是集合中的元素不满足非递减关系,也就是递减关系。
所以问题就转换成为了求最长递减子序列(LDS)的长度
POJ 1065(LDS DP) AC代码:
#include <cstdio> #include <algorithm> #include <cstring> #include <iostream> using namespace std; const int N = 5005; int t,n,d[N]; bool vis[N]; struct node { int w,l; }T[N]; int cmp(node n1, node n2) { if(n1.w == n2.w) return n1.l < n2.l; else return n1.w < n2.w; } void solve() { int ans = 0; sort(T,T+n, cmp); memset(d, 0, sizeof(d)); for(int i = 0; i < n; i++) { int mx = 0; for(int j = 0; j < i; j++) if(T[j].l > T[i].l && d[j] > mx) mx = d[j]; d[i] = mx+1; ans = max(ans, d[i]); } printf("%d\n", ans); } int main() { //freopen("in.txt", "r", stdin); scanf("%d", &t); while(t--) { scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d %d", &T[i].w, &T[i].l); solve(); } return 0; }
POJ 1065(贪心) AC代码:
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N = 5005; int t,n,d[N]; bool vis[N]; struct node { int w,l; }T[N]; int cmp(node n1, node n2) { if(n1.w == n2.w) return n1.l < n2.l; else return n1.w < n2.w; } void solve() { int ans = 0; sort(T,T+n, cmp); memset(vis, false, sizeof(vis)); for(int i = 0; i < n; i++) { if(vis[i]) continue; int last = T[i].l; for(int j = i+1; j < n; j++) if(T[j].l >= last && !vis[j]) { vis[j] = true; last = T[j].l; } ans++; } printf("%d\n", ans); } int main() { scanf("%d", &t); while(t--) { scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d %d", &T[i].w, &T[i].l); solve(); } return 0; }
poj 1065 Wooden Sticks / hdu 1257 最少拦截系统 DP 贪心
标签:
原文地址:http://www.cnblogs.com/sevenun/p/5455086.html