最长公共子序列+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. Redis Index

    Indexes 集群 主从模型 哨兵机制与RAFT算法 实践 单机多实例 开启Sentinel 存储 持久化 RDB 与 AOF 数据结构 内存管理 事务 并发问题 分布式锁 整体图 中间件 Jedi ...

  2. 微信小程序云开发更换云开发环境

    小程序云开发环境初始化默认是第一个环境,但是我们可以指定环境id //app.js App({ onLaunch: function () { if (!wx.cloud) { console.err ...

  3. C语言--第2次作业

    1.本章学习总结 1.1思维导图 1.2本章学习体会及本章代码量 1.2.1学习体会 不同于前几周简单的条件语句等,这一周开始学习循环结构for,while语句,甚至是多种语句嵌套使用,让我直接感受到 ...

  4. echarts生成的图表大小怎么随屏幕的大小改变自适应

    最近在做图表,记录一下用到的知识点,当做自己的日记吧,会不断添加新内容 1,echarts生成的图表大小怎么随屏幕的大小改变自适应? this.chart.setOption(this.options ...

  5. Ant Design of React 框架使用总结1

    一.  为什么要用UI 框架 统一了样式交互动画 . Ui框架会对样式,交互动画进行统一,保证了系统风格完整统一,不像拼凑起来的. 兼容性 ,不是去兼容IE 6 7 8那些低版本浏览器,而是对主流的标 ...

  6. 2 - Binary Search & LogN Algorithm

    254. Drop Eggs https://www.lintcode.com/problem/drop-eggs/description?_from=ladder&&fromId=1 ...

  7. 了解UI Automator Viewer

    uiautomatorviewer 是Android SDK自带的工具,通过截屏分析XML布局文件的方式,为用户提供控件信息查看服务.该工具位于SDK目录下的tools\bin子目录下,可以看到它是通 ...

  8. Docker五大优势:持续集成、版本控制、可移植性、隔离性和安全性

    随着Docker技术的不断成熟,越来越多的企业开始考虑使用Docker.Docker有很多的优势,本文主要讲述了Docker的五个最重要优势,即持续集成.版本控制.可移植性.隔离性和安全性. 对于Do ...

  9. 雷林鹏分享:jQuery EasyUI 数据网格 - 自定义分页

    jQuery EasyUI 数据网格 - 自定义分页 数据网格(datagrid)内置一个很好特性的分页功能,自定义也相当简单.在本教程中,我们将创建一个数据网格(datagrid),并在分页工具栏上 ...

  10. Aspose.Words的Merge Field

    今天应客户要求,修改导出word模板.使用的是Aspose.Words插件.这个程序原是同事所写,且自己对Aspose不是很了解.在替换模板上花费了一些时间. 先来一张图:下图是原来的模板.现在要求删 ...