Uva10635 LCS

题目链接:http://vjudge.net/contest/137498#problem/G

题意:有两个长度为p+1和q+1的序列,每个序列的中的各个元素互不相同,且都是1~n^2之间的整。两个序列的第一个元素均为1。求出A和B的最长公共子序列长度。

输入:  T  //测试组数

           n p q

    A : p+1个数

    B:q+1个数

输出:Case t: len

 

思路:因为n*n=62500 LCS的算法 O(pq)很慢,而且数组也开不下,所以可以转化为求LIS(O(nlogn))。

 

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=62505;
const int INF=1000000000;

int s[maxn],dp[maxn];
int num[maxn];  /// num[x]为整数x的新编号,num[x]=0表示x没有在A中出现过

int main()
{
    int T;
    scanf("%d",&T);
    for(int t=1; t<=T; t++)
    {
        int N,p,q,x;
        scanf("%d%d%d",&N,&p,&q);
        memset(num,0,sizeof(num));
        for(int i=1; i<=p+1; i++)
        {
            scanf("%d",&x);
            num[x]=i;
        }
        int n=0;
        for(int i=0; i<q+1; i++)   ///转化为求s的LIS
        {
            scanf("%d",&x);
            if(num[x])
                s[++n]=num[x];
        }
        int len=1;
        dp[1]=s[1];
        for(int i=2; i<=n; i++)
        {
            if(s[i]>dp[len]) dp[++len]=s[i];
            else dp[upper_bound(dp+1,dp+1+len,s[i])-dp]=s[i];
        }
        printf("Case %d: %d\n",t,len);
    }
    return 0;
}

 

posted @ 2016-10-23 20:05  a_clown_cz  阅读(125)  评论(0)    收藏  举报