美文网首页
最长公共子序列(LCS)问题

最长公共子序列(LCS)问题

作者: 背负代码的宇智波 | 来源:发表于2019-01-01 15:52 被阅读0次

问题描述

给定两个 1 到 n 的排列 A,B (即长度为 n 的序列,其中 [1,n] 之间的所有数都出现了恰好一次)。

求它们的最长公共子序列长度。

子序列: 一个序列A = a1,a2,……an,中任意删除若干项,剩余的序列叫做A的一个子序列。也可以认为是从序列A按原顺序保留任意若干项得到的序列。

求解算法

对于母串X=<x1,x2,⋯,xm>, Y=<y1,y2,⋯,yn>,求LCS与最长公共子串。

暴力解法

假设 m<n, 对于母串X,我们可以暴力找出2的m次方个子序列,然后依次在母串Y中匹配,算法的时间复杂度会达到指数级O(n∗2的m次)。显然,暴力求解不太适用于此类问题。

动态规划

假设Z=<z1,z2,⋯,zk>是X与Y的LCS, 我们观察到
如果Xm=Yn,则Zk=Xm=Yn,有Zk−1是Xm−1与Yn−1的LCS;
如果Xm≠Yn,则Zk是Xm与Yn−1的LCS,或者是Xm−1与Yn的LCS。
因此,求解LCS的问题则变成递归求解的两个子问题。但是,上述的递归求解的办法中,重复的子问题多,效率低下。改进的办法——用空间换时间,用数组保存中间状态,方便后面的计算。
先假设有 C[i,j] = | LCS(x[1...i] , y(1...j)) |,则有


image.png
// n:表示两序列长度
// a:描述序列 a(这里需要注意的是,由于 a 的下标从 1 开始,因此 a[0] 的值为-1,你可以忽略它的值,只需知道我们从下标 1 开始存放有效信息即可) 
// b:描述序列b(同样地,b[0] 的值为 -1)
// 返回值:最长公共子序列的长度
#include <cstdio>  
#include <cstring>  
#include <cmath>  
#include <cstdlib>  
#include <algorithm>  
#include <queue>  
#include <stack>  
#include <map>  
#include <set>  
#include <vector>  
#include <iostream>
#include <utility>
using namespace std;
#define PII pair<int,int> 
#define PIII pair<pair<int,int>,int> 
#define mp make_pair
#define pb push_back
#define sz size() 
#define fi first
#define se second
typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
vector<int> pos,a,b,f;
int getAns(int n,vector<int>a,vector<int>b){
    f.resize(n+1);pos.resize(n+1);
    for(int i=0;i<=n;++i) f[i]=n+2;
    for(int i=1;i<=n;++i){
        pos[b[i]]=i;
    }
    for(int i=1;i<=n;++i){
        a[i]=pos[a[i]];
    }
    f[0]=0;
    for(int i=1;i<=n;++i)
    *lower_bound(f.begin(),f.end(),a[i])=a[i];
    return int(lower_bound(f.begin(),f.end(),n+1)-f.begin())-1;
}
int main(){
    int n;scanf("%d",&n);
    a.resize(n+1);b.resize(n+1);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    printf("%d\n",getAns(n,a,b));
    return 0;
}

输出结果

5
1 2 4 3 5
5 2 3 4 1
2

相关文章

  • lintcode 最长公共子序列

    给出两个字符串,找到最长公共子序列(LCS),返回LCS的长度。说明最长公共子序列的定义: 最长公共子序列问题是在...

  • 子序列

    最长公共子序列(LCS)(lintcode 77) 描述:给出两个字符串,找到最长公共子序列(LCS),返回LCS...

  • LCS问题

    LCS问题包括最长公共子序列和最长公共子串,其中,最长公共子串要求必须连续。 对于二者的求解方式 最长公共子序列:...

  • (6)动态规划(上) LCS

    LCS 问题描述: 在两个给定的序列中, 找出最长的公共子序列(Largest Common Sequence),...

  • 最长公共子序列

    最长公共子序列问题( Longest Common Subsequence problem,LCS) 是求两个给定...

  • LCS详解

    LCS是什么 LCS是Longest Common Subsequence的缩写,即最长公共子序列。一个序列,如果...

  • LCS解析,打印最大长度和路径

    LCS是什么 LCS是Longest Common Subsequence的缩写,即最长公共子序列。它与子串的区别...

  • LCS:最长公共子序列

    LCS(最长公共子序列)是动态规划里的一道经典的问题。动态规划

  • Java解决LCS(Longest Common Sequenc

    问题描述 LCS问题可以分作最长公共子序列问题和最长公共子集问题,其区别在于前者要求的是连续的属于两个字符串序列的...

  • 深度透析最长公共子序列算法

    最长公共子序列(Longest Common Subsequenen, LCS) 1、概念 动态规划(dynami...

网友评论

      本文标题:最长公共子序列(LCS)问题

      本文链接:https://www.haomeiwen.com/subject/eybnlqtx.html