最长公共子序列问题(LCS) 动态规划

子序列的概念

 一个序列A中任意删除若干项,剩余的序列叫做A的一个子序列。

也可以认为是从序列A按原顺序保留任意若干项得到的序列。

子序列不是子集,它和原始序列的元素顺序是相关的。

公共子序列的概念

顾名思义,如果序列C既是序列A的子序列,同时也是序列B的子序列,则称它为序列A和序列B的公共子序列。

最长公共子序列

A和B的公共子序列中长度最长的(包含元素最多的)叫做A和B的公共子序列。

子序列、公共子序列以及最长公共子序列都不唯一,但显然最长公共子序列的长度是一定的。

所以,最长公共子序列问题并不是求那个序列,而是求最长的那个长度。

动态规划

定义LCS(x, y)表示x和y的最长公共子序列的长度

下面求A和B的最长公共子序列长度

A[x]和B[y]分别是两个序列的最后一项

首先,考虑子序列最后一项

A[x] == B[y]:

  那么它们一定是最长公共子序列的最后一项,可以反证

A[x] != B[y]:

  又分为两种情况:从A中去掉A[x],从B中去掉B[y]

  这两种继续回到上面递归求解,最后取其中较大的一个的结果

递推公式如下:

 按照公式可以写出递归解法:

下面是伪代码

也有非递归解法:

 如何构造一个LCS

 构造表格

第一步,将序列和下标画成表格

初始化表格

然后就是一行行地填表

填表规则:

如果横竖相等,就取左上角加一

如果横竖不等,就取左边和上边的最大值

 

 构造LCS

 构造表格时从第一个往后

构造LCS时要从最后一个向前

横竖相等就减一,向左上角走

横竖不等就取左面和上面较大的那一个

如果横竖不等,且上面和左面一样大,就随便选一个

走到0就结束了,经历的路径就是所求的最长公共子序列

因为最长公共子序列不是唯一的嘛

参考:

https://blog.csdn.net/hrn1216/article/details/51534607

 https://blog.csdn.net/so_geili/article/details/53737001

https://blog.csdn.net/lz161530245/article/details/76943991

猜你喜欢

转载自www.cnblogs.com/wbyixx/p/9358082.html