POJ 1065 Wooden Sticks 最长不上升子集 偏序定理

来源:互联网 发布:太平洋官方软件 编辑:程序博客网 时间:2024/06/05 08:56

题目链接: POJ—1065 Wooden Sticks
题目大意: 一堆木头拥有l,w两个值,必须按照l<=l’&&w<=w’的顺序才能排成一队,求多少组。
题目分析: l为第一关键字,w为第二关键字从小到大排列。然后求w中的最长不上升子集。

PS:
1、里面那个vector用的不好。。。应该直接数组,然后把vec[0] = INF就比较方便了,不得已只能把r设成-1,写的好丑。。。
2、最长不上升子序列我用的是《挑战程序设计》P65的dp,其实还可以优化成二分搜索(懒得改了)
3、关于偏序定理,参见POJ1065+POJ3636(偏序定理) - 笑巧 - 博客园

/***********************************Problem: 1065       User: ChenyangDuMemory: 732K        Time: 16MSLanguage: G++       Result: Accepted************************************/#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;int T,n;struct Wood{int l,w;}wood[5000+5];bool cmp (Wood a,Wood b){    if(a.l == b.l){        return a.w < b.w;    }    return a.l < b.l;}int main(){    scanf("%d",&T);    while(T--){        scanf("%d",&n);        for(int i=0;i<n;i++){            scanf("%d%d",&wood[i].l,&wood[i].w);        }        sort(wood,wood+n,cmp);        int vec[5000+5];        int r = -1;        for(int i=0;i<n;i++){            int w = wood[i].w;            if(r == -1 || w < vec[r]){                vec[++r] = w;                continue;            }else{                for(int j=r-1;j>=-1;j--){                    if(j == -1 || vec[j] > w){                        vec[j+1] = w;                        break;                    }                }            }        }        cout<<r+1<<endl;    }    return 0;}
原创粉丝点击