hdu1025 dp+二分查找 nlogn最长上升子序列
1 #include<stdio.h> 2 #include<string.h> 3 int a[500005],b[500005],d[500005]; 4 void sort(int l,int r) 5 { 6 int i=l,j=r,x=a[(i+j)/2],y; 7 while (i<=j) 8 { 9 while (a[i]<x) i++; 10 while (x<a[j]) j--; 11 if (i<=j) 12 { 13 y=a[i]; a[i]=a[j]; a[j]=y; 14 y=b[i]; b[i]=b[j]; b[j]=y; 15 i++; j--; 16 } 17 } 18 if (i<r) sort(i,r); 19 if (l<j) sort(l,j); 20 } 21 void doit(int l,int r,int num) 22 { 23 int mid=(l+r)/2; 24 if (num<d[l]) {d[l]=num; return; } 25 if (l+1==r) {d[r]=num; return; } 26 if (num<d[mid]) doit(l,mid,num); 27 else doit(mid+1,r,num); 28 return; 29 } 30 int main() 31 { 32 int n,i,maxlen,t=0; 33 while (~scanf("%d",&n)) 34 { 35 for (i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]); 36 sort(1,n); 37 memset(d,0,sizeof(d)); maxlen=0; 38 for (i=1;i<=n;i++) 39 { 40 if (b[i]>d[maxlen]) 41 { 42 maxlen++; 43 d[maxlen]=b[i]; 44 } 45 else doit(1,maxlen,b[i]); 46 } 47 t++; 48 printf("Case %d:\n",t); 49 if (maxlen==1) printf("My king, at most 1 road can be built.\n\n"); 50 else printf("My king, at most %d roads can be built.\n\n",maxlen); 51 } 52 }
http://acm.hdu.edu.cn/showproblem.php?pid=1025
<补年轻时的坑>:二分不用手写,最长上升是lower_bound,最长不下降是upper_bound