- > 动规讲解基础讲解五——最长公共子序列问题
例如:
对于一个长度为n的序列,它一共有2^n 个子序列,有(2^n – 1)个非空子序列。
仍然用序列1,3,5,4,2,6,8,7和序列1,4,8,6,7,5
1,4,6,7
请注意: 最长公共子序列不唯一。
请大家用集合的观点来理解这些概念,子序列、公共子序列以及最长公共子序列都不唯一,所以我们通常说一个最长公共子序列,但显然最长公共子序列的长度是一定的。
你首先能想到的恐怕是暴力枚举?那我们先来看看:序列A有 2^n 个子序列,序列B有 2^m 个子序列,如果任意两个子序列一一比较,比较的子序列高达 2^(n+m) 对,这还没有算具体比较的复杂度。
吓着了吧?怎么办?试试使用动态规划算法!
可是,我们事先并不知道t,由定义,我们取最大的一个,因此这种情况下,有LCS(x,y) = max(LCS(x – 1, y) , LCS(x, y – 1))。
看看目前我们已经得到了什么结论:
LCS(x,y) =
(1) LCS(x - 1,y - 1) + 1 如果Ax = By
(2) max(LCS(x – 1, y) , LCS(x, y – 1)) 如果Ax ≠ By
这时一个显然的递推式,光有递推可不行,初值是什么呢?
(1) LCS(x - 1,y - 1) + 1 如果Ax = By
(2) max(LCS(x – 1, y) , LCS(x, y – 1)) 如果Ax ≠ By
(3) 0 如果x = 0或者y = 0
到此我们求出了计算最长公共子序列长度的递推公式。我们实际上计算了一个(n + 1)行(m + 1)列的表格(行是0..n,列是0..m),也就这个二维度数组LCS(,)。
输入序列A, B长度分别为n,m,计算二维表 LCS(int,int):
for x = to n do
for y = to m do
if (x == || y == ) then
LCS(x, y) =
else if (Ax == By) then
LCS(x, y) = LCS(x - ,y - ) +
else
LCS(x, y) = ) max(LCS(x – , y) , LCS(x, y – ))
endif
endfor
endfor
现在问题来了,我们如何得到一个最长公共子序列而仅仅不是简单的长度呢?其实我们离真正的答案只有一步之遥!
这对应L(x,y) = L(x,- 1 y- 1)末尾接上Ax
这对应L(x,y)= L(x – 1, y)
(2.2) LCS(x, y – 1) 如果Ax ≠ By且LCS(x – 1, y) <LCS(x, y – 1)
这对应L(x,y) = L(x, y – 1)
这对应L(x,y)=空序列
神奇吧?又一个类似的递推公式。可见我们在计算长度LCS(x,y)的时候只要多记录一些信息,就可以利用这些信息恢复出一个最长公共子序列来。就好比我们在迷宫里走路,走到每个位置的时候记录下我们时从哪个方向来的,就可以从终点回到起点一样。

今天对LCS的讲解就到这里,聪明的你是不是已经蠢蠢欲动要AC问题啦? 心动不如行动,赶快吧。
#include<iostream>
#include<cstring>
using namespace std;
int f[][];
string a,b,z;
int main()
{
while(cin>>a>>b)
{
memset(f,,sizeof(f));
int l1=a.size();
int l2=b.size();
a=' '+a;
b=' '+b;
for(int i=;i<=l1;i++)
for(int j=;j<=l2;j++)
if(a[i]==b[j])
f[i][j]=f[i-][j-]+;
else
f[i][j]=max(f[i-][j],f[i][j-]);
int i=l1,j=l2;
while(i&&j)
{
if(a[i]==b[j])
{
z=a[i]+z;
i--;j--;
}
else
{
if(f[i-][j]>=f[i][j-]) i--;
else j--;
}
}
cout<<z;
}
}
如果对你有所帮助,别忘了加好评哦;么么哒!!下次见!88
- > 动规讲解基础讲解五——最长公共子序列问题的更多相关文章
- 最长公共子序列lcs 51nod1006
推荐参考博客:动态规划基础篇之最长公共子序列问题 - CSDN博客 https://blog.csdn.net/lz161530245/article/details/76943991 个人觉得上面 ...
- LCS(最长公共子序列)动规算法正确性证明
今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下, ...
- HDU 1159 Common Subsequence (动规+最长公共子序列)
Common Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- DP_最长公共子序列/动规入门
学自:https://open.163.com/movie/2010/12/L/4/M6UTT5U0I_M6V2U1HL4.html 最长公共子序列:(本文先谈如何求出最长公共子序列的长度,求出最长公 ...
- POJ-1458 Common Subsequence(线性动规,最长公共子序列问题)
Common Subsequence Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44464 Accepted: 18186 ...
- 动态规划_基础_最长公共子序列_多种方法_递归/dp
D: 魔法少女资格面试 题目描述 众所周知,魔法少女是一个低危高薪职业.随着近年来报考魔法少女的孩子们越来越多,魔法少女行业已经出现饱和现象!为了缓和魔法少女界的就业压力,魔法少女考核员丁丁妹决定增加 ...
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...
- 从最长公共子序列问题理解动态规划算法(DP)
一.动态规划(Dynamic Programming) 动态规划方法通常用于求解最优化问题.我们希望找到一个解使其取得最优值,而不是所有最优解,可能有多个解都达到最优值. 二.什么问题适合DP解法 如 ...
- 准备NOIP2017 最长公共子序列(模版)
一些概念: (1)子序列: 一个序列A = a1,a2,--an,中任意删除若干项,剩余的序列叫做A的一个子序列.也可以认为是从序列A按原顺序保留任意若干项得到的序列.例如: 对序列 1,3,5, ...
随机推荐
- AGC16E Poor Turkeys
输入样例: 10 10 8 9 2 8 4 6 4 9 7 8 2 8 1 8 3 4 3 4 2 7 输出样例#6: 5 话说这题虽然不是很OI但是确实挺锻炼思维的 一开始以为是用并查集之类的东西维 ...
- Traceback (most recent call last): File "setup.py", line 22, in <module> execfile(join(CURDIR, 'src', 'SSHLibrary', 'version.py')) NameError: name 'execfile' is not defined
在python3环境下安装robotframework-SSHLibraray报错: Traceback (most recent call last): File "setup.py&qu ...
- 编写UI自动化测试用例原则
1.一个脚本是一个完整的场景,从用户登陆操作到用户退出系统关闭浏览器.2.一个脚本脚本只验证一个功能点,不要试图用户登陆系统后把所有的功能都进行验证再退出系统3.尽量只做功能中正向逻辑的验证,不要考虑 ...
- 最简单的SPA(单页应用)实现
$(function(){ var replacePage = function(href, onFinish){ $.get(href,{},function(raw){ var data = ra ...
- scla-基础-函数-元组(0)
//元组 class Demo2 extends TestCase { def test_create_^^(){ val yuana = (1,true,1.2,"c",&quo ...
- CF817A Treasure Hunt
思路: 起点(x1, y1),终点(x2, y2),步长(dx, -dy),(dx, dy),(-dx, -dy),(-dx, dy).只要满足abs(x1 - x2) % dx == 0 并且 ab ...
- sed -i 报错的情况
是因为替换的变量中带/的目录名 将原来的/改成#
- 【PostgreSQL-9.6.3】物化视图
PostgreSQL 9.3 以后出现了物化视图.物化视图是由实实在在的数据组成,这是和一般视图的根本区别. 1. 物化视图创建语法如下: --创建语法 CREATE MATERIALIZED VIE ...
- HDU_1072_Nightmare
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1072 题目描述:矩阵表示迷宫,0表示墙,1表示路,2表示起点,3表示终点,4表示重置炸弹时间(6秒),你需 ...
- .net core 中简单封装Dapper.Extensions 并使用sqlsuger自动生成实体类
引言 由公司需要使用dapper 同时支持多数据库 又需要支持实体类 又需要支持sql 还需要支持事务 所以采用了 dapper + dapperExtensions 并配套 生成实体类小工具的方 ...