这个问题很有意思,在生物应用中,经常需要比较两个(或多个)不同生物体的DNA片段。例如,某种生物的DNA可能为S1 = ACCGGTCGAGTGCGCGGAAGCCGGCCGAA,S2 = GTCGTTCGGAATGCCGTTGCTCTGTAAA。比较两个DNA串是想要确定它们之间的“相识度”,作为度量两种生物相近程度的指标。LCS就是寻找第三个串S3,S3满足定义:给定一个序列X = <x1,x2,...,xn>,另一个序列Y = <y1,y2,...,ym>即存在一个严格递增的X的下标序列<i1,i2,...,im>,对所有j = 1,2,...,m,满足xij = zj。例如,Z = BCDB是ABCBDAB的子序列,对应的下标为[2,3,5,7]。

  如果用暴力求解则很容易就达到指数阶的运行时间,所以显然需要优化。通过分析发现LCS问题具有最优子结构性质,于是,考虑用动态规划是一个非常不错的方案。

  显然早就有许多人对此类问题做过很多工作,不管是理论上还是实际测试,都证明动态规划可以解决这一类型的问题,有时候甚至是最优方案。如何熟练使用动态规划的一大难点在于分析问题,要理解如何使用动态规划来解决问题,首先分析问题是否具有最优子结构是重要的,然后就是通过分析问题得到递归公式,只要得到了递归公式,我们就可以使用动态规划了。

  LCS问题也不例外,经过分析和查资料,我们知道了LCS得最优子结构定理:

  令X = <x1,x2,...,xn>和Y = <y1,y2,...ym>为两个序列,Z = <z1,z2,...,zk>为X和Y的任意LCS。

  • 如果xn = ym,则zk = xn = ym且Zk - 1是Xn - 1和Ym - 1的一个LCS;
  • 如果xn ≠ ym且zk ≠ xn,说明Z是Xn - 1和Y的一个LCS;
  • 如果xn ≠ ym且zk ≠ ym,说明Z是X和Ym的一个LCS;

  然后,我们开始建立最优解的递归式。定义dp[i][j]为Xi和Yj的LCS长度。显然的,当i = 0或j = 0时,LCS = 0。再结合最优子结构定理,可得到递归式:

                (    0;                              当 i = 0 或 j = 0;
dp[i][j] = { dp[i - 1][j - 1] + 1 当 i,j > 0 且 xi = yj;
( max(dp[i][j - 1], dp[i - 1][j]) 当 i,j > 0 且 xi != yj.

  得到递归式后,就可以根据公式写出递归算法或动态规划算法:

#include <iostream>
#include <string>
#include <vector>
#include <minmax.h> class Solution {
public:
int LongestCommonSubsequence(std::string s1, std::string s2) {
if (s1.empty() || s2.empty())
return 0;
std::vector<std::vector<int> > dp(s1.size(), std::vector<int>(s2.size(), 0));
int length = 0;
for (int i = 1; i < dp.size(); i++) {
for (int j = 1; j < dp[0].size(); j++) {
if (s1[i] == s2[j])
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);
length = max(length, dp[i][j]);
}
}
return length + 1;
}
}; int main()
{
Solution solve;
std::string s1{"ABCBDAB"};
std::string s2{"ABDCABA"}; std::cout << solve.LongestCommonSubsequence(s1, s2) << std::endl; return 0;
}

  最后,类似的问题还有LIS(最长递增子序列)、LPS(最长回文子串)等等。

  参考资料:

    《算法导论》

LCS(最长公共子序列)的更多相关文章

  1. 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列

    出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...

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

    POJ 1458 Common Subsequence(LCS最长公共子序列)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?c ...

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

    LCS最长公共子序列 模板代码: #include <iostream> #include <string.h> #include <string> using n ...

  4. LCS 最长公共子序列

    区别最长公共子串(连续) ''' LCS 最长公共子序列 ''' def LCS_len(x, y): m = len(x) n = len(y) dp = [[0] * (n + 1) for i ...

  5. LCS最长公共子序列(最优线性时间O(n))

    这篇日志主要为了记录这几天的学习成果. 最长公共子序列根据要不要求子序列连续分两种情况. 只考虑两个串的情况,假设两个串长度均为n. 一,子序列不要求连续. (1)动态规划(O(n*n)) (转自:h ...

  6. LCS最长公共子序列

    问题:最长公共子序列不要求所求得的字符串在所给字符串中是连续的,如输入两个字符串ABCBDAB和BDCABA,字符串BCBA和BDAB都是他们的公共最长子序列 该问题属于动态规划问题 解答:设序列X= ...

  7. LCS最长公共子序列HDU1159

    最近一直在学习算法,基本上都是在学习动态规划以及字符串.当然,两者交集最经典之一则是LCS问题. 首先LCS的问题基本上就是在字符串a,b之间找到最长的公共子序列,比如 YAOLONGBLOG 和 Y ...

  8. POJ 2250(LCS最长公共子序列)

    compromise Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u   Descri ...

  9. LCS最长公共子序列~dp学习~4

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 Palindrome Time Limit: 4000/2000 MS (Java/Others ...

  10. Atcoder F - LCS (DP-最长公共子序列,输出字符串)

    F - LCS Time Limit: 2 sec / Memory Limit: 1024 MB Score : 100100 points Problem Statement You are gi ...

随机推荐

  1. 公告 & 留言板 & 随想录

    欢迎dalao在评论区留言 \(Q \omega Q\) 公告部分: 博客文章的更新一般被放在周末 当然还是可能会咕 自从改了博客的主题之后,文章中的引用好像都会显示出一堆乱码. 由于之前写过的博文不 ...

  2. vue使用过程中遇到的细节问题

    1. 在methods 中添加一个方法.如果这个方法使用箭头函数的话,箭头函数中的this不是当前的vue实例,所以通过this.xxx是获取不到实例上面的属性的,这时我们可以用函数的简写来获取到实例 ...

  3. Block Chain Learning Notes

    区块链是什么 区块链技术是由比特币创造的,本文也将从比特币开始进行引导,一步一步告诉大家什么是区块链.如果你想立马知道区块链是什么,也可以直接转到文章末尾的区块链定义. 区块链,可能是当下最有前景又充 ...

  4. 洛谷P1616疯狂的采药(完全背包)

    题目背景 此题为NOIP2005普及组第三题的疯狂版. 此题为纪念LiYuxiang而生. 题目描述 LiYuxiang是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的 ...

  5. c语言实现面向对象编程

    1.通用校验器接口(validator.h) #ifndef VALIDATOR_H_INCLUDED #define VALIDATOR_H_INCLUDED #include<stdbool ...

  6. 第六节:前后端交互之axios用法及async异步编程

    一. axios用法 参考: API文档: https://www.kancloud.cn/yunye/axios/234845 GitHub: https://github.com/axios/ax ...

  7. IDEA自动部署WEB工程至远程服务器(学习笔记)

    一.部署Web工程的几种方式 ①本地打war,上传至远程服务器tomcat容器即可 优点:简单粗暴 缺点:浪费时间 ②IDEA自动部署至远程服务器 优点:节省大量时间 缺点:配置稍多(第一次) 二.I ...

  8. 【笔记4-商品模块】从0开始 独立完成企业级Java电商网站开发(服务端)

    分类管理模块 数据表结构设计 分类表 CREATE TABLE.mmall_ category' ( 'id' int(11) NOT NULL AUTO_ INCREMENT COMMENT ' 类 ...

  9. 4_6 师兄帮帮忙(UVa12412)(选做)

    你好,我是外国语学院的本科生.正如你所知道的,编程是一个  在我们大学必修课,即使他/她的专业是远离计算机科学.我根本不喜欢这个 课程,因为我不擅长电脑,我不想有任何编程的尝试!  但我不得不做作业: ...

  10. laravel qq邮件配置