Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 14099 Accepted Submission(s): 4008
2 1 2 2 1 3 1 2 2 3 3 1
Case 1: My king, at most 1 road can be built. Case 2: My king, at most 2 roads can be built.
题目是要求最长递增子序列,用一般动态规划会超时。
对动态规划算法的改进,在计算每一个f(i)时,都要找出最大的f(j)(j<i)来,由于f(j)没有顺序,只能顺序查找满足aj<ai最大的f(j),如果能将让f(j)有序,就可以使用二分查找,这样算法的时间复杂度就可能降到O(nlogn)。于是想到用一个数组B来存储“子序列的”最大递增子序列的最末元素,即有B[f(j)] = aj在计算f(i)时,在数组B中用二分查找法找到满足j<i且B[f(j)]=aj<ai的最大的j,并将B[f[j]+1]置为ai。f[j]+1为以ai结尾的递增子序列长度
#include"stdio.h" #define N 500005 int p[N],f[N]; int len,n; void search() { int i,low,mid,high; f[1]=p[1]; len=1; for(i=1;i<=n;i++) { low=1; high=len; while(low<=high) { mid=(low+high)/2; if(f[mid]<p[i]) //当f[mid]==p[i]时,low不变,high减一,返回low; low=mid+1; else high=mid-1; /*if(f[mid]>=p[i]) high=mid-1; else low=mid+1;*/ } f[low]=p[i]; if(len<low) len++; } } int main() { int i,cnt=1,r,x; while(scanf("%d",&n)!=-1) { for(i=0;i<n;i++) { scanf("%d%d",&x,&r); // p[x]记录需要的r; p[x]=r; } search(); //二分快速查找 printf("Case %d:\n",cnt++); if(len==1) printf("My king, at most %d road can be built.\n\n",len); else printf("My king, at most %d roads can be built.\n\n",len); } return 0; }
Android - Activity的生存期,布布扣,bubuko.com
原文:http://blog.csdn.net/caroline_wendy/article/details/21106479