这个题如果直接LCS做会超时,然后呢就有了一个方法(我反正是想不出来QAQ),首先把输入的王子经过的从1开始标号,于是就成了一个hash映射,然后把公举经过的依照王子的对应生成编号。生成完之后,按照样例,公举的编码是 1 4 6 3 0 0 5 7,0是王子里面没出现过的,这样操作有啥用呢?你想啊,我们要求的是最长公共,标号后非零,即是两个人公共的了,由于王子编号是递增的,所以相对于王子来说,从公主中求出来的序列必定得是上升的,然后还得是最长,所以就是求hash完的最长上升子序列了
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=250+5;
int t,n,p,x,q,k;
int hasp[maxn*maxn],hasq[maxn*maxn];
int dp[maxn*maxn];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&p,&q);
memset(hasp,0,sizeof(hasp));
for(int i=1;i<=p+1;i++)
{
scanf("%d",&x);
hasp[x]=i;
}
memset(hasq,0,sizeof(hasq));
for(int i=1;i<=q+1;i++)
{
scanf("%d",&x);
hasq[i]=hasp[x];
}
memset(dp,INF,sizeof(dp));
for(int i=1;i<=q+1;i++)
if(hasq[i])//注意必须是王子中有的元素
*lower_bound(dp,dp+q+1,hasq[i])=hasq[i];
int ans=lower_bound(dp,dp+q+1,INF)-dp;
printf("Case %d: %d\n",++k,ans);
}
return 0;
}