这道题的题意是 给长度为 p+1 和 q+1的序列,每个序列中的各个元素互不影响,且长度都是 1-n^2之间的整数。两个序列的第一个元素均为1,求出A,B最长公共子序列长度。
思路就是 这题看着像LCS,但是n有250,用LCS肯定会超时,所以要换一个方法。
这里每个序列中的各个元素互不相同 所以可以把A重新编写,A:1,7,5,4,8,3,9 可以变成1,2,3,4,5,6,7 按照这个对照,B可以变成1,4,6,3,0,0,5,7这样就变成了求B的LIS 这样复杂度就变成了O(nlogn)
AC代码:
/* ***********************************************
Author :yzkAccepted
Created Time :2016/5/18 16:12:47
TASK :ggfly.cpp
LANG :C++
************************************************ */
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int maxn=250*250;
int hash[maxn],stack[maxn];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m,i,j,p,q,t,cas=1;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&p,&q);
memset(hash,0,sizeof(hash));
p=p+1;
q=q+1;
for(i=1;i<=p;i++)
{
int v;
scanf("%d",&v);
hash[v]=i;
}
int top=0;
stack[top]=-1;
for(i=1;i<=q;i++)
{
int v;
scanf("%d",&v);
v=hash[v];
if(v)
{
if(v>stack[top])
stack[++top]=v;
else
{
int l=1,r=top;
while(l<=r)
{
int m=(l+r)>>1;
if(stack[m]<v)
l=m+1;
else
r=m-1;
}
stack[l]=v;
}
}
}
printf("Case %d: %d\n",cas++,top);
}
return 0;
}