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);
    }
}
posted @ 2018-03-31 01:14  KuroNekonano  阅读(136)  评论(0编辑  收藏  举报