[Luogu] P1439 【模板】最长公共子序列

题目描述

给出1-n的两个排列P1和P2,求它们的最长公共子序列。

输入输出格式

输入格式:

第一行是一个数n,

接下来两行,每行为n个数,为自然数1-n的一个排列。

输出格式:

一个数,即最长公共子序列的长度

说明

【数据规模】

对于50%的数据,n≤1000

对于100%的数据,n≤100000

题目解析

因为是给定的两串数字是排列,所以可以利用一下排列的性质。

思考一下,如果两串数字中有一串是形如1 2 3 4 5 .....的,那么这个题的难度会大大降低,转变为求另一个串中的最长不下降子序列。

最长不下降子序列可以用nlogn的时间求出,这样就可以卡进时限了。

又发现数字的排列方式对本题影响不大,所以我们离散化一下,把第一个串强行离散成1 2 3 4 5 ......等于把每个数字映射一下,然后nlogn就可以了

Code

#include<iostream>
#include<cstdio>
using namespace std;

const int MAXN = 100005;

int n,len;
int a[MAXN],b[MAXN];
int id[MAXN],dp[MAXN],d[MAXN];

int main() {
    scanf("%d",&n);
    for(int i = 1;i <= n;i++) {
        scanf("%d",&a[i]);
        id[a[i]] = i;
    }
    for(int i = 1;i <= n;i++) {
        scanf("%d",&b[i]);
    }
    int tmp;
    for(int i = 1;i <= n;i++) {
        if(id[b[i]] > d[len]) {
            d[++len] = id[b[i]];
            dp[i] = len;
            continue;
        }
        tmp = lower_bound(d + 1,d + 1 + len,id[b[i]]) - d;
        d[tmp] = id[b[i]];
        dp[i] = tmp;
    }
    printf("%d
",len);
}
原文地址:https://www.cnblogs.com/floatiy/p/9532550.html