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