n*logn最长上升序列
hdu1025
2分查找+DP;
View Code
#include<stdio.h> int a[500001],b[500001]; int main() { int u=1,n,x,y,i,j; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) { scanf("%d%d",&x,&y); a[x]=y; } int len=1;b[1]=a[1]; for(i=1;i<=n;i++) //2分查找 { int low=1,high=len,mid; while(low<=high) { mid=(low+high)/2; if(b[mid]>=a[i])high=mid-1; else low=mid+1; } b[low] = a[i]; if(low>len) len++; } printf("Case %d:\n",u++); if(len==1)printf("My king, at most %d road can be built.\n",len); else printf("My king, at most %d roads can be built.\n",len); printf("\n"); } }
NOIP1999
分别求一组数的最长不上升序列和最长上升序列
2分查找+DP
View Code
#include<stdio.h> #define maxn 30001 int a[maxn],b[maxn],n,len1,len2; int search1(int temp) { int mid,high=len1,low=1; while(low<=high) { mid=(low+high)/2; if(temp>a[mid])high=mid-1; else low=mid+1; } if(low>len1)len1++; return low; } int search2(int temp) { int mid,high=len2,low=1; while(low<=high) { mid=(low+high)/2; if(temp<=b[mid])high=mid-1; else low=mid+1; } if(low>len2)len2++; return low; } int main() { int i,temp; while(scanf("%d",&n)!=EOF) { scanf("%d",&temp); a[1]=b[1]=temp;n-=1;len1=len2=1; while(n--) { scanf("%d",&temp); int k=search1(temp);a[k]=temp; k=search2(temp);b[k]=temp; } printf("%d\n%d\n",len1,len2); } return 0; }


浙公网安备 33010602011771号