题目大意:
给你两串整数,要求你输出最长公共子序列(串的长度是100000.)时间限制:1000 ms | 内存限制:65535 KB
所以无论是时间上还是空间上这都是需要进行比较精心的优化过后才行。这题我做了老半天然后各种优化最终都没成功,都是超时了,然后dp数组还开不到100000*100000;而且这题网上的代码页找不到,最后只能求助大师了,看完大师的代码后才恍然大悟,只恨自己太笨。仰天长啸,然后将解题思路奉献给更多的人吧。
#include<stdio.h>
#include<string.h>
#define N 100010
inta[N],b[N],dp[N];
int Find(int L,int R,intvalue)//最长递增子序列二分查找。
{
while(L<=R)
{
intmid=(L+R)/2;
if(dp[mid]>=value&&dp[mid-1]<=value)
return mid;
elseif(dp[mid]
L=mid+1;
else
R=mid-1;
}
return L;
}
int main()
{
int n,m;
int i,j;
int x;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(i=1;i<=n;i++)//按顺序记录a串中各字符的位置
{
scanf("%d",&x);
a[x]=i;
}
j=0;
for(i=1;i<=m;i++)
{
scanf("%d",&x);
if(a[x]) //只保存a,b串公有字符
b[++j]=a[x];//将问题转化成了最长递增子序列a[x]是x在a串的位置
}
intlen=j;//记录b串的长度len
intR=0;//用来保存最长递增子序列的长度
j=0;
dp[0]=-1;//初始值吗!
for(i=1;i<=len;i++)//动态规划最长递增子序列,这个不理解的话可以网上自己找!!
{
if(b[i]>dp[R])
j=++R;
else
j=Find(1,R,b[i]);
dp[j]=b[i];
}
printf("%d\n",R);//输出最长递增子序列的长度不就行了
}
}
好了,我相信只要你认真读完代码,应该也就对本题了然于心了。