最长公共子序列+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. vscode下运行matlab记录

    Linux下安装MATLAB可参照以下链接: https://blog.csdn.net/qq_31285709/article/details/82083902 在vscode 中运行.m文件. 首 ...

  2. bzoj1452 [JSOI2009]Count ——二维树状数组

    中文题面,给你一个矩阵,每一个格子有数字,有两种操作. 1. 把i行j列的值更改 2. 询问两个角坐标分别为(x1,y1) (x2,y2)的矩形内有几个值为z的点. 这一题的特点就是给出的z的数据范围 ...

  3. flask No such command "init-db".

    在Daily目录下,使用cmd窗口执行,不要使用IDE的命令行 set FLASK_APP=DLY set FLASK_ENV=development flask init_app

  4. java 有序数组合并

    有序数组合并,例如: 数组 A=[100, 89, 88, 67, 65, 34], B=[120, 110, 103, 79, 66, 35, 20] 合并后的结果 result=[120, 110 ...

  5. 线程demo异常处理

    今天写了个线程小demo,出现了异常, 如下: Traceback (most recent call last): File "threading.py", line 1, in ...

  6. kafka 创建消费者报错 consumer zookeeper is not a recognized option

    在做kafka测试的时候,使用命令bin/kafka-console-consumer.sh --zookeeper 192.168.0.140:2181,192.168.0.141:2181 --t ...

  7. Cordova入门系列(一)创建项目

    Cordova是什么? 初学Cordova的人,虽然了解一点点,知道Cordova是用来将html, css, js变成app的,但并不知道到底是怎么用的,原理是什么.经常会有这样的困惑: 它是一个可 ...

  8. javascript的几个知识点scoping, hoisting, IIFE

    Scoping--作用域 ES6之前只有函数作用域.ES6加入块级作用域.用let声名的变量是块作用域内有效,用var声名的变量在函数作用域与块作用域里有效. Hoisting--提升 Hoistin ...

  9. 使用querybuilder做忽略大小写查询的例子

    自定义Predicate: import com.day.cq.search.Predicate; import com.day.cq.search.eval.AbstractPredicateEva ...

  10. 基于Docker的Mysql主从复制搭建

    来源:https://www.cnblogs.com/songwenjie/p/9371422.html?tdsourcetag=s_pctim_aiomsg   为什么基于Docker搭建? 资源有 ...