UVA 10635 Prince and Princess

题意:
求两数字串的最长公共子序列(LCS)。

思路:
LCS的时间复杂度为O(nn),因为数据量大,所以会超时。
又因为数字串互不相同,所以可以LCS转LIS(最长上升子序列),LIS有时间复杂度O(n
log(n))的解法。–二分法

先对第一个数字串进行处理,用map记录下每个值所对应的下标(位置),再处理第二个数字串,将其中在第一个数字串中出现的数字构建一个数组,新数组的值记录的是该数字在第一个数字串里的位置。
最后通过最长上升子序列(LIS)求得答案。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#define inf 0x7fffffff

using namespace std;
int n,p,q,a[90000],dp[90000];
int main()
{
    ios::sync_with_stdio(false);
    int T,x;
    scanf("%d",&T);
    for(int k=1;k<=T;k++)
    {
        map<int,int> m;
        memset(dp,0,sizeof(dp));
        int num=0;
        scanf("%d%d%d",&n,&p,&q);
        for(int i=0;i<=p;i++)
        {
            scanf("%d",&x);
            m[x]=i+1;
        }
        for(int i=0;i<=q;i++)
        {
            scanf("%d",&x);
            if(m[x])
            {
                a[num++]=m[x];
            }
        }
        dp[0]=a[0];
        int len=1;
        for(int i=1;i<num;i++)
        {
            if(dp[len-1]<a[i])
            {
                dp[len++]=a[i];
            }
            else
            {
                int id=lower_bound(dp,dp+len,a[i])-dp;
                dp[id]=a[i];
            }
        }
        printf("Case %d: %d\n",k,len);
    }
    return 0;
}

发布了19 篇原创文章 · 获赞 0 · 访问量 187

猜你喜欢

转载自blog.csdn.net/qq_43032263/article/details/104418729