最长公共子序列+sdutoj2080改编:

http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2788/pid/2080

传送门: https://blog.csdn.net/sunshine_pb/article/details/21820159

设序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最长公共子序列为Z={z1,z2,…,zk},

记:    Xk为序列X中前k个连续字符组成的子序列,

Yk为序列Y中前k个连续字符组成的子序列,

Zk为序列Z中前k个连续字符组成的子序列,

显然有下式成立:

(1)若xm=yn,则zk=xm=yn,且Zk-1是Xm-1和Yn-1的最长公共子序列;

(2)若xm≠yn且zk≠xm,则Z是Xm-1和Y的最长公共子序列;

(3)若xm≠yn且zk≠yn,则Z是X和Yn-1的最长公共子序列。

可见,两个序列的最长公共子序列包含了这两个序列的前缀序列的最长公共子序列。

要找出序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最长公共子序列,可按下述递推方式计算:

当xm=yn时,找出Xm-1和Yn-1的最长公共子序   列,然后在其尾部加上xm即可得到X和Y的最长公共子序列;

当xm≠yn时,必须求解两个子问题:找出Xm-1和Y的最长公共子序列以及Xm和Yn-1  的最长公共子序列,这两个公共子序列中的较长

者即为X和Y的最长公共子序列

设L[i][j]表示子序列Xi和Yj的最长公共子序列的长度,可得如下动态规划函数:

L[0][0] = L[i][0] = L[0][j] = 0           (1≤i≤m,1≤j≤n)

L[i][j]只是记录子序列的长度,要打印得到XmYn具体的最长公共子序列,设二维表S[m+1][n+1],其中S[i][j]表示在计算L[i][j]的过程中的搜索状态,并且有:

若S[i][j]=1,表明ai=bj,则下一个搜索方向是S[i-1][j-1];

若S[i][j]=2,表明ai≠bj且L[i][j-1]≥L[i-1][j],则下一个搜索方向是S[i][j-1];

若S[i][j]=3,表明ai≠bj且L[i][j-1]<L[i-1][j],则下一个搜索方向是S[i-1][j]。

举例:序列X=(a,b,c,b,d,b),Y=(a,c,b,b,a,b, d, b,b),建立两个(m+1)×(n+1)的二维表L和表S,分别存放搜索过程中得到的子序列的长

度和状态。

下面代码为sdutoj2080改编代码:

 /* */
# include <bits/stdc++.h>
using namespace std; int CommonOrder( int len1, int len2, char x[], char y[], char z[]);
int L[][];
int S[][];
int main()
{
char a[], b[], z[];
int i, t, len1, len2;
while( gets(a) && gets(b) )
{
len1 = strlen(a);
len2 = strlen(b);
t = CommonOrder(len1, len2, a, b, z);
printf("%d\n", t);
for( i=; i<=t; i++ )
{
printf("%c%c", z[i], i==t?'\n':' ');
}
}
return ;
} int CommonOrder(int m, int n, char x[], char y[], char z[])
{
int j, i, k;
for( j=; j<=n; j++ )
{
L[][j] = ;
}
for( i=; i<=m; i++ )
{
L[i][] = ;
}
for( i=; i<=m; i++ )
{
for( j=; j<=n; j++ )
{
if( x[i-]==y[j-] )
{
L[i][j] = L[i-][j-]+;
S[i][j] = ;
}
else if( L[i][j-]>=L[i-][j] )
{
L[i][j] = L[i][j-];
S[i][j] = ;
}
else
{
L[i][j] = L[i-][j];
S[i][j] = ;
}
}
}
i = m;
j = n;
k = L[m][n];
while( i>= && j>= )
{
if( S[i][j]== )
{
z[k] = x[i-];
k--;
i--;
j--;
}
else if( S[i][j]== )
{
j--;
}
else
{
i--;
}
}
return L[m][n];
}

算法分析:在算法中,

第一个for循环的时间性能是O(n);

第二个for循环的时间性能是O(m);

第三个循环是两层嵌套的for循环,其时间性能是O(m×n);

第四个for循环的时间性能是O(k),而k≤min{m,n},所以,算法的时间复杂性是O(m×n)。

动态规划———最长公共子序列(LCS)的更多相关文章

  1. 动态规划 最长公共子序列 LCS,最长单独递增子序列,最长公共子串

    LCS:给出两个序列S1和S2,求出的这两个序列的最大公共部分S3就是就是S1和S2的最长公共子序列了.公共部分 必须是以相同的顺序出现,但是不必要是连续的. 选出最长公共子序列.对于长度为n的序列, ...

  2. 动态规划----最长公共子序列(LCS)问题

    题目: 求解两个字符串的最长公共子序列.如 AB34C 和 A1BC2   则最长公共子序列为 ABC. 思路分析:可以用dfs深搜,这里使用到了前面没有见到过的双重循环递归.也可以使用动态规划,在建 ...

  3. 动态规划——最长公共子序列LCS及模板

    摘自 https://www.cnblogs.com/hapjin/p/5572483.html 这位大佬写的对理解DP也很有帮助,我就直接摘抄过来了,代码部分来自我做过的题 一,问题描述 给定两个字 ...

  4. 动态规划之最长公共子序列LCS(Longest Common Subsequence)

    一.问题描述 由于最长公共子序列LCS是一个比较经典的问题,主要是采用动态规划(DP)算法去实现,理论方面的讲述也非常详尽,本文重点是程序的实现部分,所以理论方面的解释主要看这篇博客:http://b ...

  5. 《算法导论》读书笔记之动态规划—最长公共子序列 & 最长公共子串(LCS)

    From:http://my.oschina.net/leejun2005/blog/117167 1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要 ...

  6. 编程算法 - 最长公共子序列(LCS) 代码(C)

    最长公共子序列(LCS) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定两个字符串s,t, 求出这两个字符串最长的公共子序列的长度. 字符 ...

  7. C++版 - Lintcode 77-Longest Common Subsequence最长公共子序列(LCS) - 题解

    版权声明:本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C++版 - L ...

  8. 1006 最长公共子序列Lcs

    1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdks ...

  9. POJ 1458 Common Subsequence(最长公共子序列LCS)

    POJ1458 Common Subsequence(最长公共子序列LCS) http://poj.org/problem?id=1458 题意: 给你两个字符串, 要你求出两个字符串的最长公共子序列 ...

  10. 51Nod 1006:最长公共子序列Lcs(打印LCS)

    1006 最长公共子序列Lcs  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). ...

随机推荐

  1. gulp插件实现压缩一个文件夹下不同目录下的js文件(支持es6)

    gulp-uglify:压缩js大小,只支持es5 安装: cnpm: cnpm i gulp-uglify -D yarn: yarn add gulp-uglify -D 使用: 代码实现1:压缩 ...

  2. 常见的JavaWeb安全问题及修复

    1.SQL注入:程序向后台数据库传递SQL时,用户提交的数据直接拼接到SQL语句中并执行,从而导入SQL注入攻击. 字符型注入:黑色部分为拼接的问题参数 select * from t_user wh ...

  3. Linear Regression with machine learning methods

    Ha, it's English time, let's spend a few minutes to learn a simple machine learning example in a sim ...

  4. 推荐一个SAM文件或者bam文件中flag含义解释工具

    SAM是Sequence Alignment/Map 的缩写.像bwa等软件序列比对结果都会输出这样的文件.samtools网站上有专门的文档介绍SAM文件.具体地址:http://samtools. ...

  5. vue 学习笔记(一)

    对于 vue 官网给的教程由浅及深,非常容易上手.我之前有过 react 项目开发经验,对 webpack 打包,脚手架这一类的东西并不陌生.所以也是我上手比较快的原因吧.简单将我在学习 vue 中遇 ...

  6. Java——ping & telnet实现

    ping & telnet 实现类: import org.springframework.data.web.JsonPath; import java.io.IOException; imp ...

  7. [python]目录及文件操作

    Python OS模块和shutil模块 获取路径 # 获取当前路径 pwd = os.getcwd() # 获取上级路径 a_pwd = os.path.abspath(os.path.dirnam ...

  8. python ssh登录linux 上传和下载文件

    #!usr/bin/python# coding: utf-8 import paramikoimport jsonremotedir='/tmp/log'remotefile = 'bst_mana ...

  9. 搭建日志收集系统时使用客户端连接etcd遇到的问题

    问题: 在做日志收集系统时使用到etcd,其中server端在linux上,首先安装第三方包(windows)(安装过程可能会有问题,我遇到的是连接谷歌官网请求超时,如果已经出现下面的两个文件夹并且文 ...

  10. 多组图自动无限循环(swiper轮播)

    前两天的一个项目中遇到多组图片无限轮播,当时采用了swiper 但是没有解决让它无限轮播.今天再次尝试了一下发现是自己的样式写错了.今天在这里写一下,为了给自己一个警醒不要犯同样的错误 首先先引入一下 ...