动态规划(DP)---LCS(the Longest Common Subsequence)
来源:互联网 发布:js模块化开发框架 编辑:程序博客网 时间:2024/05/01 01:48
0 暴力求解两个序列的最长公共子序列(LCS)
字符串
第一次遇到这种题时,我会不假思索地将字符串
子序列的个数为:
这个跟二项展开式很像,二项展开式是这个样子的:
所以,一个长度为
那么,使用暴力的方式,找出两个长度分别为
由此,暴力破解的时间复杂度就是:
如何?暴力破解所消耗的时间是指数规模(exponential time)的,这样的速度就是龟速!
1 动态规划(Dynamic Programming)
动态规划通常用来求解最优化问题(optimization problem)。这类问题可以有很多可行解,每个解都有一个值,我们希望寻找具有最优值(最小值或最大值)的解。我们称这样的解为问题的一个最优解(an optimal solution),而不是最优解(the optimal solution),因为可能有多个解达到最优值。
我们通常按如下4个步骤来设计一个动态规划算法:
1,刻画一个最优解的结构特征。
2,递归地定义最优解的值。
3,计算最优解的值,通常采用自底向上的方法。
4,利用计算出的信息构造一个最优解。
————自《算法导论》机械工业出版社
并不是所有的最优问题都可以使用动态规划来求解,使用动态规划必须满足两个问题:
1. 最优子问题(optimal subproblems)。
2. 重叠子问题(overlapping subproblems)。
2 使用动态规划求解LCS
按照上面提到的4个步骤来设计一个求解LCS的动态规划算法。
2.1 刻画一个最优解的结构特征
定义:
那么:
因此,LCS 最优解的结构特征就是
2.2 递归定义最优解的值
根据2.1定义的最优解的结构特征,写出
下面证明式(2)的正确性。
2.3 计算最优解的值,通常采用自底向上
2.3.1 自顶向下
参照归纳表达式(2),写出LCS递归算法如下:
LCS(x,y,i,j)if x[i] == x[j] c[i,j]=LCS(x,y,i-1,j-1)+1else c[i,j]=max(LCS(x,y,i-1,j),LCS(x,y,i,j-1))return c[i,j]
在最坏情况下,即
递归树的高度为:
由蓝色虚线框出的部分可以看出,递归算法存在重复运算,这也验证了动态规划的第二个特征:重叠子问题。
改进算法,将子问题的解存储起来(备忘法),下次求解相同子问题时直接取出解:
LCS(x,y,i,j)if c[i,j]!=nil return c[i,j]if x[i] == x[j] c[i,j]=LCS(x,y,i-1,j-1)+1else c[i,j]=max(LCS(x,y,i-1,j),LCS(x,y,i,j-1))return c[i,j]
使用备忘法后,独立子问题的规模就只有
那么,独立子问题的规模是怎么知道的呢?答案就在算法中的数组
2.3.2 自底向上(bottom-up)
从前面的自顶向下可以看出,算法有很多的重复计算,虽然采用备忘法可以去掉重复,但是程序极为不清晰。一般来说,真正的动态规划更多的是采用自底向上的方法来去重复。
参照式(2)归纳式,可以很容易地写出自底向上的伪代码,其求解方法就是自底向上填充数组
LCS(x,y,m,n)for i=0 to m-1 for j=0 to n-1 if x[i]=y[j] c[i,j]=c[i-1,j-1]+1 else c[i,j]=max(c[i-1,j],c[i,j-1])return c[m,n]//代码没有考虑 c[-1,-1],由于 c[-1,-1]没有任何前缀字符,所以 c[-1,-1]=0, c[-1,*]=c[*,-1]=0
根据代码来填充数组
如图所示,蓝色边框就是计算后的数组
2.4 利用计算出的信息构造一个最优解
那么利用数组
- 动态规划(DP)---LCS(the Longest Common Subsequence)
- UVA - 10405 Longest Common Subsequence(动态规划:LCS)
- UVA 10405 Longest Common Subsequence (dp + LCS)
- UVa 10405 Longest Common Subsequence (DP&LCS)
- HDU 1159 Common Subsequence (动态规划LCS)
- 【common subsequence】动态规划+回溯求LCS
- 动态规划解最长公共子序列问题LCS(longest common subsequence)
- Dynamic Programming longest common subsequence(LCS) 动态规划之最长公共子序列
- 最长公共子序列 (LCS,longest common subsequence problem) 动态规划
- [动态规划] [LCS算法] 最长公共子序列 longest common subsequence
- [动态规划]UVA10405 - Longest Common Subsequence
- HDU 1159 Common Subsequence(最长公共子序列(LCS) 动态规划(DP))
- LCS(Longest Common Subsequence)算法
- 最长公共子序列LCS(The longest common subsequence)
- poj 动态规划DP - 1458 Common Subsequence
- POJ 1458 Common Subsequence (DP 动态规划)
- [DP]Longest Common Subsequence
- 【算法导论学习-29】动态规划经典问题02:最长公共子序列问题(Longest common subsequence,LCS)
- IOS中XML大文件解析
- ZOJ 3714 Java Beans(暴力)
- iOS开发UI篇—UIScrollView控件介绍
- 简析TCP的三次握手与四次分手
- mysql乐观锁总结和实践
- 动态规划(DP)---LCS(the Longest Common Subsequence)
- 实现button的图文并茂
- vc socket tcp编程的简单实例
- Effective C++ 读书笔记之----条款01:视 C++ 为一个语言联邦
- Lua中的table函数库
- android中布局使用大全
- ZOJ 3712 Hard to Play
- Android第三方账号登录
- ZOJ 3706 Break Standard Weight(暴力)