http://acm.hdu.edu.cn/showproblem.php?pid=1677
这道题纠结了N个小时,因为原来找的模板里少了两个等号。。。结果就是错在了我一直觉得不会错的LIS里,让我认清了上升和非降的区别?
下降数列的个数等于LIS,和导弹拦截那道题基本一致
ps:连着三道LIS看排名都进了前三,好开心~
View Code
#include <iostream> #include <algorithm> using namespace std ; int dp[10001],p[20001]; typedef struct L{ int w,h; }L; L kk[20001]; int cmp(L a,L b) { if(a.w!=b.w)return b.w < a.w ; return a.h < b.h ; } int LIS(int n) { int l,r,m,i,tail = 0; for ( dp[ ++ tail ] = p[ 1 ],i = 2 ; i <= n ; ++ i ) { if ( dp[ tail ] <= p[ i ] ) { dp[ ++ tail ] = p[ i ]; continue; } for ( m=((r=tail)+(l=1)>>1) ; l < r ; m=(l+r)>>1 ) if ( dp[ m ] <= p[ i ] ) l = m+1; else r = m; dp[ m ] = p[ i ]; } return tail; } inline bool scan_d(int &num) { char in;bool IsN=false; in=getchar(); if(in==EOF) return false; while(in!='-'&&(in<'0'||in>'9')) in=getchar(); if(in=='-'){ IsN=true;num=0;} else num=in-'0'; while(in=getchar(),in>='0'&&in<='9'){ num*=10,num+=in-'0'; } if(IsN) num=-num; return true; } int main() { int t,n; scan_d(t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) { scan_d(kk[i].w); scan_d(kk[i].h); } sort(kk+1,kk+1+n,cmp); for(int i=1;i<=n;i++) p[i]=kk[i].h; int ans=LIS(n); printf("%d\n",ans); } return 0; }