题目链接: 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: ChenyangDu
Memory: 732K Time: 16MS
Language: 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;
}