• POJ 1065 Wooden Sticks / hdu 1257 最少拦截系统 DP 贪心


    参考链接: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
    ", 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;
    }
    

      

    5.4:做了第二天的一道题,求最长上升子序列的长度。然后用了nlogn的解法,而求最长下降子序列也一样可以用该方法。

    POJ 1065(LDS 的nlogn)AC代码:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int N = 5005;
    int t,n,d[N];
    //d[i] 长度为i+1的最长下降子序列中的末尾元素的最大值 
    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, -1, sizeof(d));
    	
    	for(int i = 0; i < n; i++)
    	{
    		*lower_bound(d,d+n,T[i].l, greater<int>()) = T[i].l;
    	}
    	printf("%d
    ", lower_bound(d,d+n,-1, greater<int>())-d);
    }
    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
    ", 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;
    }
    

      

  • 相关阅读:
    元组
    字典
    列表
    数据类型-字符串(str)
    python安装和首次使用
    javac++的stl解决重复的元素
    c++二分法求一个数的完全平方数
    双指针法----->求数组中两数之和
    java的二分法求一个数的平方根
    Java递归加上二分搜索将有序数组转化为平衡二叉树2
  • 原文地址:https://www.cnblogs.com/sevenun/p/5455086.html
Copyright © 2020-2023  润新知