• [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);
    }
  • 相关阅读:
    安徽.NET俱乐部4月份活动图片
    C++ string和数字间的任意转换
    利用C++特性 析构对象(ScopeGuard.h)
    ffmpeg第三方库
    Apifox软件使用技巧
    工作流撤回(activity5)
    pom文件详解
    Java内部类详解成员内部类,局部内部类,匿名内部类,静态内部类
    Docker 详解
    JDK8 新特性 Lambda表达式
  • 原文地址:https://www.cnblogs.com/floatiy/p/9532550.html
Copyright © 2020-2023  润新知