最长公共子序列(动态规划) nyoj36

本文详细介绍了最长公共子序列(LCS)的概念及其动态规划解决方案。通过实例解析自顶向下和自底向上的求解过程,并附带代码,帮助读者深入理解算法思想。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence)。

  做了一些动态规划的题的同学应该知道 做这类题大多是通过自底向上(或自顶向下)的方式求出每一状态的最优 解,

 最后得出问题的最优解。(一般用数组(或别的)存它的当前状态下的最优解,求当前状态如果需要由之前的状态 求得时,直接用就可以了)

   现在我们就以串 A:a s d f  串 B:a d f s d 这两个串为例, 做一下最长公共子序列。

(1)自顶向下:


                    d[i][j] = d[i-1][j-1] + 1;        A[i] =B[j]    

LCS(I, j) =  d[i][j]= max(d[i-1][j], d[i][j-1])  A[i]≠B[j]  


d[i][j]代表 A中前i个字符与B中前j个字符的最长公共子序列的值,

当A[i]与B[j]相等时,那么d[i][j] 就等于d[i-1][j-1] + 1(应为每一个状态存的都是当前最优解,d[i-1][j-1]+1一定是d[i][j]的最优解);

当A[i]与B[j]不相等时,那么就往前一状态看,等于前一状态,d[i][j]的前一状态有两个①d[i][j-1](A中前i个与B中前j-1个的状态)②d[i-1][j](A中前i-1个与B中前j个的状态),所以d[i][j]= max(d[i-1][j], d[i][j-1]);

看图分析一下:

d[3][3] : 可以看做是d[asd][adf] = max(d[asd][ad], d[as][adf]);

d[4][3]:  可以看成d[asdf][adf] = d[asd][ad] + 1;  (希望可以看懂!!)

 


01234
0
asdf
1a1111
2d1122
3f1123
4s1223
5d1233

 

ny36题

 

 

(2)自底向上

和第一种方法差不多, 就是方向问题, 第一个看明白了, 这个就很容易看懂了(这个用了递归),

当求d[i][j]时 如果A[i]=B[j] , 那么就由 d[i-1][j-1]这一状态求得; 如果A[i]!=B[j] , 那么他就应该是由 d[i-1][j] 和d[i][j-1]求得。


注:下图是两个串x:ABCBDAB  y:BDCABA(这个图是截的图)

 

 

代码附上

好好理解一下!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值