1598 序列问题III(nlogn最长公共子序列)
Description
有俩个长度分别为p和q的序列A和B,每个序列的各个元素互不相同,且每个元素的大小都是1~(p和q中的最大值)之间的正整数。
俩个序列的第一个元素都为1,求出A和B的最长公共子序列长度。
Input
输入第一行为数据组数T(T<=20)。每组数据包括3行,第一行为2个整数p和q(1<=p,q<=10000),
第二行包含序列A,其中第一个数为1。
第三行包含序列B,格式同序列A。
Output
对于每组数据,输出A和B的最长公共子序列的长度。
Sample Input
2
3 2
1 2 3
1 2
7 8
1 7 5 4 8 3 2
1 4 3 5 6 2 8 7
Sample Output
2
4
Hint
对于第二组数据最长公共子序列为1,4,3,2
将LCS问题转换为LIS问题,记录相同数字的位序,与另一个串的位序相匹配,并求LIS
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
int t,p,q,pos[10008],a[10008],maxx[10008];
scanf("%d",&t);
while(t--)
{
memset(pos,0,sizeof(pos));
scanf("%d%d",&p,&q);
for(int i=1;i<=p;i++)scanf("%d",&a[i]),pos[a[i]]=i;
for(int i=1;i<=q;i++)scanf("%d",&a[i]),a[i]=pos[a[i]];
maxx[1]=a[1];
int flag=1;
for(int i=2;i<=q;i++)
{
if(a[i]>maxx[flag])
maxx[++flag]=a[i];
else
{
int half=lower_bound(maxx+1,maxx+flag,a[i])-maxx;
maxx[half]=a[i];
}
}
printf("%d\n",flag);
}
}