算法导论随笔(十三):动态规划与最长公共子序列(LCS)

本文详细探讨了动态规划(Dynamic Programming, DP)的最优子结构和子问题重叠特性,以最长公共子序列(Longest Common Subsequence, LCS)问题为例进行讲解。通过对比暴力求解法与DP求解法,阐述了DP如何降低复杂度,从O(2^n)降至O(n^2),并给出了具体的DP求解LCS问题的伪代码及实例解析。" 113677621,10549094,Python编程:基础与练习,"['Python', '基础语法', '算术操作', 'math函数', '表达式控制']
摘要由CSDN通过智能技术生成

前言

动态规划(Dynamic programming)与前文算法导论随笔(二): 归并排序与分治策略中提到的分治策略类似,都是通过组合子问题的解来求解原问题。

分治策略不同的是,在分治策略中,每一个子问题是独立的,而动态规划中每一个子问题之间则有重叠的情况。举例来说,归并排序使用的是分治策略,因为它的每一个子问题都是将一个子数组中的数进行排序,而每个子问题中排序的子数组与其他子问题中的子数组并没有任何关系,即互相独立。因此,对于每一个子数组,归并排序算法都要对其进行重新排序。例如有两组长度为2的子数组,在对它们分别排序之后要进行归并操作,此时产生一个长度为4的数组,而该数组仍然需要重新排序。

动态规划适用的问题,比如本文中介绍的最长公共子序列问题中,每一个子问题并不是互相独立的,而且每一个子问题的解都是对该子问题的子问题的解的扩充。也就是说,一个子问题的解依赖于该子问题的子问题的解。假设原问题为A,A的子问题为B,B的子问题为C。那么对于最小的子问题C,我们就可以把它的解记录下来,在之后求解B的时候,它会使用到C的解,此时我们直接去查记录即可,不用再计算一次C的解。当B的解求出之后,我们也记录下B的解,这样求A的解时,查看记录中B的解即可。

上面的解释用书中的语言说,就是动态规划所具备的两个要素:最优子结构子问题重叠。最优子结构指的是,上文中A的解中,其实也包含了B的解和C的解(这也就解释了为什么A的解会依赖于B和C的解)。子问题重叠意味着我们可以使用一种缓存机制来存储子问题的解,并在之后要用到的时候通过直接查询缓存来获取。

最长公共子序列问题

最长公共子序列(Longest common subsequence, LCS)问题是一个经典的可以使用动态规划来求解的问题。给定两个字符串S1和S2,该问题要求我们求出它们的最长的公共子序列。这里我们先举个例子说一下子序列是什么。

对于字符串ABCDEFGHIJK,该字符串的一个子序列为ACEGIJK,另一个子序列为DFGHK。而DAGH则不是ABCDEFGHIJK的子序列。也就是说,子序列不要求相似的字母连续,这也是子序列子串的区别。

由此可知,对于字符串S1=“ABCD"和S2=“ACDE”,它们的公共子序列有"AC”,“CD"和"ACD”。其中最长的为ACD,因此ACD即为S1和S2的最长公共子序列。

暴力求解法

最长公共子序列问题的最基本解决方法就是暴力求解:先求出S1的所有子序列;然后遍历S1的每一个子序列,看它是否也是S2的子序列,如果是的话则把它记录下来;接着在所有的公共子序列中,找出长度最大的那个。这种求解方法的复杂度极高,甚至不是多项式时间内所能解决的。比如我们假定S1的长度为n,那么S1的子序列有2n个,所以仅仅是找出S1的所有子序列就需要O(2n)的时间。如果读者知道
f (

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值