poj1065
贪心,这里提一下dilworth定理很厉害(http://www.lxlsosi.tk/2011/05/26/%E5%81%8F%E5%BA%8F%E9%9B%86-dilworth-%E5%AE%9A%E7%90%86-poj-1065-3636-1548/)
@:因为要消除多算的一次,由dilworth定理将题目从最少不降序列划分转为最长下降子序列,若a.w>b.w则在二分计算时会多算一次,因为实际上两者l是相等的(注意这里下降定义为l,w同时小于),所以通过将小者放在前面,来出去多算的一次。
#include <stdio.h> #include <algorithm> using namespace std; int a,b,len,k[5000]; struct node { int l,w; }m[5000]; bool cmp(node a,node b) { if(a.l==b.l) return a.w<b.w;//@ else return a.l<b.l; } int search(int key) { int p=0,q=len,t; while(p<q) { t=(q+p)>>1; if(k[t]==key) return t; else if(k[t]<key) q=t; else p=t+1; } return p; } int f() { k[0]=m[0].w; len=0; for(int i=1,t;i<b;++i) { t=search(m[i].w); if(k[t]>m[i].w) k[++len]=m[i].w; else k[t]=m[i].w; } return len+1; } int main() { scanf("%d",&a); for(int i=0;i<a;++i) { scanf("%d",&b); for(int j=0;j<b;++j) scanf("%d %d",&m[j].l,&m[j].w); sort(m,m+b,cmp); printf("%d\n",f()); } return 0; }