赞
踩
题目:
给定两个序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},求X和Y的最长公共子序列。
1 最长公共子序列概念
实现明确一个点就是,子序列是一个序列中去掉若干元素后得到的序列,也就是说子序列的元素下标是递增的就行,不需要在原序列中连续。
最长公共子序列,显而易见就是序列X和Y都有的最长的子序列。
2 BruteForce 暴力求解法
对于序列X的所有长度不超过Y的子序列,都检查是否也是Y的子序列,在检查过程中记录长度做长的。
假设X长度小于Y,X有m个元素,每个元素都有2种选择,在或不在,所以X一共有2m个不同子序列。此方法需要指数时间。
3 DP 动态规划法
① 最优子结构
首先我们来检查下LCS问题能不能用DP来做。
DP的问题,需要分成的子问题具有最优子结构性质(问题的最优解中包含着每个子问题的最优解),子问题高度重复性,(当然不用把这个理解成必须,只是说这样的问题比较适合用DP来做)。
假设X和Y的最长公共子序列为Z={z1,z2,…,zk},
则把LCS问题,分成下面这样的几个子问题:
(1)若xm=yn,则zk=xm=yn,且Zk-1是Xm-1和Yn-1的最长公共子序列。
(2)若xm≠yn,且zk≠xm,则Zk是Xm-1和Yn的最长公共子序列。
(2)若xm≠yn,且zk≠yn,则Zk是Xm和Yn-1的最长公共子序列。
现在来证明一下,以上的子问题具有最优子结构性质,用反证法,
(1) 若zk不等于xm,因为xm=yn,所以把xm加在zk后面,{z1,z2,…,zk,xm}是X和Y的长度为k+1的公共子序列,这与Z是X和Y的最长公共子序列矛盾,因此,必有zk=xm=yn,Zk-1。
若Zk-1不是Xm-1和Yn-1的最长公共子序列,则Xm-1和Yn-1存在长度比k-1大的公共子序列,则将xm加在其后面,就产生了一个X和Y的长度比k大的公共子序列了,这与这与Zk是X和Y的最长公共子序列矛盾,
综上两点,故zk=xm=yn,且Zk-1是Xm-1和Yn-1的最长公共子序列。
(2)若Zk不是Xm-1和Yn的最长公共子序列,则Xm-1和Yn还存在更长的最长公共子序列W,则W也是X和Y的公共子序列,且W长度>k,这与Z(长度为k)是X和Y的最长公共子序列矛盾。故Zk是Xm-1和Yn的最长公共子序列。
(3)若Zk不是Xm和Yn-1的最长公共子序列,则Xm和Yn-1还存在更长的最长公共子序列W,则W也是X和Y的公共子序列,且W长度>k,这与Z(长度为k)是X和Y的最长公共子序列矛盾。故Zk是Xm和Yn-1的最长公共子序列。
综上三点,两个序列最长公共子序列包含了这两个序列的前缀的最长公共子序列,(这句话有点拗口,其实就是X和Y的LCS包含了X1≤r≤m和Y1≤s≤n的LCS)因此最长公共子序列具有最优子结构性质。
② 子问题的递归结构
用C[i][j]记录序列Xi和Yj的LCS长度。
③求最优值,输出LCS
为了构造出LCS,引入一个二维数组b[m][n],用来记录c[i][j]的值是由哪个子问题得到的。
(1)b[i][j]=1,则表示Xi和Yj的LCS是从Xi-1和Yj-1的LCS得到的,在Xi-1和Yj-1的LCS后加上一个xi得到。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。