【动态规划】最长公共子序列
最长公共子序列
给出两个序列text1和text2,要求求出这两个序列的最长公共子序列和最长公共子序列长度。
**最长公共子序列的含义:**这里的子序列可以不是连续的,只要相对位置是符合的就算,比如abdfs和adef的最长公共子序列是adf。
例题:求出acfsc(text1)和acs(text2)的最长公共子序列。
1️⃣.划分子问题
对于求text1和text2的最长公共子序列,从只有一个字符时候开始求解,求出只有一个字符的时候的最长公共序列,然后扩大问题,求出前两个字符的最长公共子序列,不断扩大问题规模,直到达到最大规模。
2️⃣.确定动态规划方程
这里先列出求长度时的模拟过程,通过模拟的过程分析出如何递推,找出动态规划方程。
dp表格,最长公共子序列长度表格
text1|text2 | a | c | s | |
---|---|---|---|---|
0 | 0 | 0 | 0 | |
a | 0 | 1 | 1 | 1 |
c | 0 | 1 | 2 | 2 |
f | 0 | 1 | 2 | 2 |
s | 0 | 1 | 2 | 3 |
c | 0 | 1 | 2 | 3 |
第二行:t1只有a和t2取a,这时候相等,那么长度就是1,t1不变,由于t1只有一个元素a,所以第二行都为1;
第三行:t1取ac,t2取a,这个时候t1的c和t2的c不相等,但是t1的前一个a和t2的a相等,所以取dp[i] [j]的上方的值dp[i-1] [j]填充到当前值。
第三行:t1取ac,t2取acs,这个时候c和s不等,当前值的左方值是更大,t1的ac和t2的ac,所以取左方dp[i] [j-1]填充到dp[i] [j]。
通过观察表格不难发现,当前值dp[i] [j]是由三个方向推出来的,左上方,左方,上方,进一步可以确定动态规划方程。
- t1[i]==t2[j]
d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + 1 , t e x t 1 [ i ] = = t e x t 2 [ j dp[i][j] = dp[i-1][j-1]+1,text1[i]==text2[j dp[i][j]=dp[i−1][j−1]+1,text1[i]==text2[j
- t1[i]!=t2[j]
d p [ i ] [ j ] = M a x ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) , t e x t 1 [ i ] ! = t e x t 2 [ j ] dp[i][j]=Max(dp[i-1][j],dp[i][j-1]),text1[i]!=text2[j] dp[i][j]=Max(dp[i−1][j],dp[i][j−1]),text1[i]!=text2[j]
为了方便递推,dp数组的第一行和第一列设置为0,也就是t1和t2是空串的时候,同样,由于dp数组对应的字符的i和j不是从0开始,所以t1和t2数组使用i和j索引的时候要注意避免越界。
3️⃣:递推填写表格
确定动态规划方程后,通过双重for循环便可以实现表格的填写,dp数组的右下角的值即为t1和t2的最长公共子序列长度。
4️⃣:回溯求最长公共子序列
填写表格求出最长公共子序列后还需要求出是那些字符组成,为了实现这个功能,还需要再用一个二维数组state来存当前dp数组求解中每个值是如何推出的状态,这里定为1(t1[i]==t2[j] 从左上角推出),2(从左边推出),3(从上方推出),当然标志的定义是随意的,只要可以达到区分的目的即可。
5️⃣:注意
明确dp数组的含义:dp[i] [j]代表t1[i]和t2[j]所组成的最长公共子序列长度。
💻:代码实现
__EOF__

本文链接:https://www.cnblogs.com/wlunan/p/18538042.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)