概述
动态规划在查找有很多重叠子问题的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存递归时的结果,因而不会在解决同样的问题时花费时间。
动态规划只能应用于有
最优子结构的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。简单地说,问题能够分解成子问题来解决。
最长公共子序列(Longest Common Subsequence, LCS)。
题目:如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,
则字符串一称之为字符串二的子串。
注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中。
请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。
例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子序列,则输出它们的长度4,并打印任意一个子序列。
请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。
例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子序列,则输出它们的长度4,并打印任意一个子序列。
1. 描述一个LCS
给定一个序列X={x1, x2, x3, ..., xm} 对于i=0, 1, 2, ... , m, 定义X的第i个前缀为Xi={x1, x2, x3, ... , xi}。例如如果X={A, B, C, B, D, A, B}, 则X4={A, B, C, B}, 而X0是个空序列。
LCS最优子结构
设X={x1, x2, ..., xm}和Y={y1, y2, ... , yn}为两个序列,并设Z={z1, z2, ... , zk}为X和Y的任意一个LCS。
1). if xm = yn, then zk=xm=yn and Zk-1 is the LCS of Xm-1 and Yn-1.
2). if xm != yn, then if zk != xm => Z is the LCS of Xm-1 and Y.
3). if xm != yn, then if zk != yn => Z is the LCS of Yn-1 and X.
2. 一个递归解
设c[i, j] is the length of Xi and Yj
then
|---- 0 if i=0 or j=0
c[i, j] = |---- c[i-1, j-1] + 1, if i, j>0 && xi=yj
|---- max{c[i, j-1], c[i-1, j]}, if i, j > 0 && xi != yj
3. 计算LCS长度
LCS-LENGTH(X, Y) m <- X.length n <- Y.length for(i <- 1 to m) do c[i, 0] <- 0 for(j <- 0 to n) do c[0, j] <- 0 for i <- 1 to m do for j <- 1 to n if xi==yj c[i,j]=c[i-1, j-1]+1 else if c[i-1, j] >= c[i, j-1] c[i,j]=c[i-1, j] else c[i, j]=c[i, j-1] return c