题意:王子和公主从 (1,1)走到(n,n)找出他们有多少次同时站在同一格上。
第一个数组p[i]:王子在i位置时是第p[i]步。
第二个数组:王子和公主在同一格时,王子是第几步。
所以只要找出这些步数的最长上升子序列就可以了!!!因为步数是从小到大不能往后退,所以是找出上升序列。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
using namespace std;
#define maxn 250*250+1
int dp[maxn],p[maxn],q[maxn];
int Lis(int n,int a[maxn])
{
int len=1,i,low,high,mid;
dp[1]=a[1];
for(i=2;i<=n;i++)
{
low=1;
high=len;
while(low<=high)
{
mid=(low+high)/2;
if(a[i]>dp[mid])
low=mid+1;
else
high=mid-1;
}
dp[low]=a[i];
if(low>len)
len=low;
}
return len;
}
int main()
{
int i,k,temp,cas=1;
int n,a,b,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&a,&b);
memset(p,-1,sizeof(p));
for(i=1;i<=a+1;i++)
{
scanf("%d",&k);
p[k]=i; /*重新定义第一个序列*/
}
/*
for(i=1;i<=20;i++)
{
cout<<p[i]<<" ";
}
cout<<endl;*/
for(i=1;i<=b+1;i++)
{
scanf("%d",&q[i]);
q[i]=p[q[i]]; /*第二个序列相对于第一个序列的顺序*/
}
/*
for(i=1;i<=20;i++)
{
cout<<q[i]<<" ";
}
cout<<endl;*/
/* temp=k=0;
dp[temp]=q[1];
for(i=2;i<=b+1;i++)
{
if(q[i]==-1)continue;
if(q[i]>dp[temp])
dp[++temp]=q[i];
else
{
k=lower_bound(dp,dp+temp,q[i])-dp;
dp[k]=q[i];
}
}
*/
int ans=Lis(b+1,q);
printf("Case %d: %d\n",cas,ans);
cas++;
}
}