动态规划解决最长公共子序列问题(转)

原文链接

动态规划法

经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题。简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加。

解决思想:

为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法。

【问题】 求两字符序列的最长公共字符子序列

问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列。令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X的子序列,存在X的一个严格递增下标序列<i0,i1,…,ik-1>,使得对所有的j=0,1,…,k-1,有xij=yj。例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列。

//在这里,可以类比为数列中的子数列。

考虑最长公共子序列问题如何分解成子问题,设A=“a0,a1,…,am-1”,B=“b0,b1,…,bm-1”,并Z=“z0,z1,…,zk-1”为它们的最长公共子序列。不难证明有以下性质:

(1) 如果am-1=bn-1,则zk-1=am-1=bn-1,且“z0,z1,…,zk-2”是“a0,a1,…,am-2”和“b0,b1,…,bn-2”的一个最长公共子序列;

(2) 如果am-1!=bn-1,则若zk-1!=am-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列;

(3) 如果am-1!=bn-1,则若zk-1!=bn-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列。

这样,在找A和B的公共子序列时,如有am-1=bn-1,则进一步解决一个子问题,找“a0,a1,…,am-2”和“b0,b1,…,bm-2”的一个最长公共子序列;如果am-1!=bn-1,则要解决两个子问题,找出“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列和找出“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列,再取两者中较长者作为A和B的最长公共子序列。

求解:

引进一个二维数组c[][],用c[i][j]记录X[i]与Y[j] 的LCS 的长度,b[i][j]记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向。
我们是自底向上进行递推计算,那么在计算c[i,j]之前,c[i-1][j-1],c[i-1][j]与c[i][j-1]均已计算出来。此时我们根据X[i] = Y[j]还是X[i] != Y[j],就可以计算出c[i][j]。

问题的递归式写成:

回溯输出最长公共子序列过程:

算法分析:
由于每次调用至少向上或向左(或向上向左同时)移动一步,故最多调用(m + n)次就会遇到i = 0或j = 0的情况,此时开始返回。返回时与递归调用时方向相反,步数相同,故算法时间复杂度为Θ(m + n)。

定义:点击这里

http://baike.baidu.com/view/2020307.htm?fr=aladdin

动态规划解决最长公共子序列问题(转),布布扣,bubuko.com

时间: 2024-12-24 23:14:01

动态规划解决最长公共子序列问题(转)的相关文章

算法——动态规划篇——最长公共子序列

问题描述      最长公共子序列,英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列.       解决最长公共子序列,一种常用的办法,就是穷举法,组合出所有的情况,但是这样对于长序列的情况来说,是非常不实际.. 假设现在有两个序列,x[]={'A','B','C','B','D','A','B'};y[]={'B','D','C','A'

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

 动态规划法 经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题.简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加. 为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法. [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列

【算法导论之七】动态规划求解最长公共子序列

一.动态规划的概念 动态规划(Dynamic Programming)是通过组合子问题的解而解决整个问题的.分治算法是指将问题划分成一些独立的子问题,递归地求解各子问题,然后合并子问题的解而得到原始问题的解,与此不同,动态规划适用于子问题不是独立的情况,也就是各个子问题包含公共的子问题.在这种情况下,采用分治法会做许多不必要的工作,即重复地求解公共地子问题.动态规划算法对每个子问题只求解一次,将其结果保存在一张表中,从而避免每次遇到各个子问题时重新计算答案. 动态规划通常应用于最优化问题.此类问

算法导论--动态规划(最长公共子序列)

最长公共子序列问题(LCS) 给定两个序列X=?x1,x2,x3...xm?和Y=?y1,y2,y3...xn?,求X和Y的最长公共子序列. 例如:X=?A,B,C,B,D,A,B?,和Y=?B,D,C,A,B,A?,的最长公共子序列为?B,C,B,A?,长度为4: 对于此问题,可以采用暴力求解的方式来比对,即穷举出X的所有子序列,用每个子序列与y做一 一比较.假如X序列共有m个元素,对每个元素可以决定选或不选,则X的子序列个数共有2m个,可见与长度m呈指数阶,这种方法效率会很低. 动态规划 前

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

tips : 本文内容是参考了很多著名博客和自己的思考得出的,如有不当欢迎拍砖. 先简单说一下动态规划 通俗地说:动态规划就是将一个可以划分为子问题的问题进行递归求解,不过动态规划将大量的中间结果保存起来, 不管它们是否会用得到,从而在后面的递归求解过程中可以快速求解.由此可以看得出来动态规划是一个以牺牲空间 为代价换取时间的算法. 对于最长公共子序列的题目不用多说,现在来分析一下LCS的动态规划解决思路: 一.首先先观察问题是否符合动态规划最明显的两个特征:最优子结构和重叠子问题 方便起见,以

动态规划求解最长公共子序列

动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解.与分治法不同的是,适合于用动态规划求解的问题,经分解得到的子问题往往不是互相独立的.若用分治法来解决这类问题,则分解得到的子问题数目太多,以至于最后解决原问题需要耗费指数时间.然而,不同子问题的数目常常只有多项式量级.在用分治法求解时,有些子问题被重复计算了许多次.如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,从而得到多项式

九度OJ 1042 Coincidence (动态规划求最长公共子序列)

题目1042:Coincidence 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1689 解决:898 题目描述: Find a longest common subsequence of two strings. 输入: First and second line of each input case contain two strings of lowercase character a-z. There are no spaces before, inside or aft

闭关修炼 动态规划1——最长公共子序列(UVA111)

经典算法题每日演练——第四题 最长公共子序列 (来自于转载:http://www.cnblogs.com/huangxincheng/archive/2012/11/11/2764625.html) 一: 作用 最长公共子序列的问题常用于解决字符串的相似度,是一个非常实用的算法,作为码农,此算法是我们的必备基本功. 二:概念 举个例子,cnblogs这个字符串中子序列有多少个呢?很显然有27个,比如其中的cb,cgs等等都是其子序列,我们可以看出 子序列不见得一定是连续的,连续的那是子串. 我想

动态规划求解最长公共子序列问题

LCS是求两个字符串,最长的公共部分,中间可以间隔其他的元素.例如,字符串s1=''mzjawxu'',s2=''xmjyauz'',仔细分析下,大体可以看出最长公共子序列是''mjau'',我们需要一套科学严格的方法来求解.这个问题是DP问题(动态规划问题).动态规划问题:就是当前问题的求解依赖于上一个子问题,上一个子问题又依赖于前一个子问题,子问题无限递归. 记: Xi=﹤x1,?,xi﹥即X序列的前i个字符 (1≤i≤m)(前缀) Yj=﹤y1,?,yj﹥即Y序列的前j个字符 (1≤j≤n