




已阅读5页,还剩17页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
动态规划解最长公共子序列问题 2009-05-30 21:28 36702人阅读 评论(36) 收藏 举报 c算法动态规划法 经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题。简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加。 为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法。【问题】 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列。令给定的字符序列X=“x0,x1,xm-1”,序列Y=“y0,y1,yk-1”是X的子序列,存在X的一个严格递增下标序列,使得对所有的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,用cij记录Xi与Yj 的LCS 的长度,bij记录cij是通过哪一个子问题的值求得的,以决定搜索的方向。我们是自底向上进行递推计算,那么在计算ci,j之前,ci-1j-1,ci-1j与cij-1均已计算出来。此时我们根据Xi = Yj还是Xi != Yj,就可以计算出cij。问题的递归式写成: 回溯输出最长公共子序列过程:算法分析:由于每次调用至少向上或向左(或向上向左同时)移动一步,故最多调用(m + n)次就会遇到i = 0或j = 0的情况,此时开始返回。返回时与递归调用时方向相反,步数相同,故算法时间复杂度为(m + n)。 代码:#include#include#defineMAXLEN100voidLCSLength(char*x,char*y,intm,intn,intcMAXLEN,intbMAXLEN).inti,j;for(i=0;i=m;i+)ci0=0;for(j=1;j=n;j+)c0j=0;for(i=1;i=m;i+).for(j=1;j=cij-1).cij=ci-1j;bij=1;else.cij=cij-1;bij=-1;voidPrintLCS(intbMAXLEN,char*x,inti,intj).if(i=0|j=0)return;if(bij=0).PrintLCS(b,x,i-1,j-1);printf(%c,xi-1);elseif(bij=1)PrintLCS(b,x,i-1,j);elsePrintLCS(b,x,i,j-1);intmain(intargc,char*argv).charxMAXLEN=.ABCBDAB;charyMAXLEN=.BDCABA;intbMAXLENMAXLEN;intcMAXLENMAXLEN;intm,n;m=strlen(x);n=strlen(y);LCSLength(x,y,m,n,c,b);PrintLCS(b,x,m,n);return0;最长公共子序列(动态规划法解决)最长公共子序列(动态规划法解决)(网上转载,该文章分析的不错)给定两个序列X=x1,x2,.,xmY=y1,y2,.,yn求X和Y的一个最长公共子序列举例X=a,b,c,b,d,a,bY=b,d,c,a,b,a最长公共子序列为LSC=b,c,b,a分析:最长公共子序列问题具有最优子结构性质设X=x1,.,xmY=y1,.,yn及它们的最长子序列Z=z1,.,zk则1、若xm=yn,则zk=xm=yn,且Zk-1是Xm-1和Yn-1的最长公共子序列2、若xm!=yn,且zk!=xm,则Z是Xm-1和Y的最长公共子序列3、若xm!=yn,且zk!=yn,则Z是Yn-1和X的最长公共子序列由性质导出子问题的递归结构当i=0,j=0时,cij=0当i,j0;xi=yi时,cij=ci-1j-1+1当i,j0;xi!=yi时,cij=maxcij-1,ci-1j/这种分析方法我总得比较有用,值得保存,所以就从book-计算机机算法设计与分析电子工业出版社中摘录出来,如果不明白,可以看一看原作。/书中只有关键部分的代码,现在已经补全/源程序#includeiostream.h#includeiomanip.h#definemax100voidLCSLength(intm,intn,char*x,char*y,char*b)inti,j,k;intcmaxmax;for(i=1;i=m;i+)ci0=0;for(i=1;i=n;i+)c0i=0;for(i=1;i=m;i+)for(j=1;j=cij-1)cij=ci-1j;k=i*(n+1)+j;bk=|;elsecij=cij-1;k=i*(n+1)+j;bk=-;voidLCS(inti,intj,char*x,char*b,intwidth)if(i=0|j=0)return;intk=i*(width+1)+j;if(bk=)LCS(i-1,j-1,x,b,width);coutxiendl;elseif(bk=|)LCS(i-1,j,x,b,width);elseLCS(i,j-1,x,b,width);voidmain()charxmax=a,b,c,b,d,a,b;charymax=b,d,c,a,b,a;intm=7;intn=6;charbmax=0;LCSLength(m,n,x,y,b);LCS(m,n,x,b,n);coutendlendl;/参考资料:计算机算法分析与设计电子工业出版社整理了下:LCS(LongestCommonSubsequences)最长公共子序列用一般的动态规划时间复杂度O(N2),但经过优化可以达到O(NlogN),下面是转载集训队某人的最长递增子序列解题报告。先回顾经典的O(n2)的动态规划算法,设Ai表示序列中的第i个数,Fi表示从1到i这一段中以i结尾的最长上升子序列的长度,初始时设Fi=0(i=1,2,.,len(A)。则有动态规划方程:Fi=maxFi,Fj+1(j=1,2,.,i-1,且AjAi)。现在,我们仔细考虑计算Fi时的情况。假设有两个元素Ax和Ay,满足(1)xyi(2)AxAyAi(3)Fx=Fy此时,选择Fx和选择Fy都可以得到同样的Fi值,那么,在最长上升子序列的这个位置中,应该选择Ax还是应该选择Ay呢?很明显,选择Ax比选择Ay要好。因为由于条件(2),在Ax+1.Ai-1这一段中,如果存在Az,AxAzay,则与选择Ay相比,将会得到更长的上升子序列。再根据条件(3),我们会得到一个启示:根据F的值进行分类。对于F的每一个取值k,我们只需要保留满足Fi=k的所有Ai中的最小值。设Dk记录这个值,即Dk=minAi(Fi=k)。PS:k长上升子序列最小的值,以便获得更长的上升子序列注意到D的两个特点:(1)Dk的值是在整个计算过程中是单调不上升的。(2)D的值是有序的,即D1D2D3.Dlen,则将Ai接在Dlen后将得到一个更长的上升子序列,len=len+1,Dlen=Ai;否则,在D1.Dlen中,找到最大的j,满足DjAi。令k=j+1,则有DjAi=Dk,将Ai接在Dj后将得到一个更长的上升子序列,同时更新Dk=Ai。最后,len即为所要求的最长上升子序列的长度。在上述算法中,若使用朴素的顺序查找在D1.Dlen查找,由于共有O(n)个元素需要计算,每次计算时的复杂度是O(n),则整个算法的时间复杂度为O(n2),与原来的算法相比没有任何进步。但是由于D的特点(2),我们在D中查找时,可以使用二分查找高效地完成,则整个算法的时间复杂度下降为O(nlogn),有了非常显著的提高。需要注意的是,D在算法结束后记录的并不是一个符合题意的最长上升子序列!这个算法还可以扩展到整个最长子序列系列问题,整个算法的难点在于二分查找的设计,需要非常小心注意。PS:搞的时候可以初始化D数组值为0./*读者的code*/#includeusingnamespacestd;/*功能:求最长子序列nlogn算法a表示输入序列n序列长度序列下标1开始flag:LIS_UP严格上升LIS_NOTDOWN非下降call:printf(%dn,LIS_UP(a,n,LIS_UP);严格上升call;printf(%dn,LIS_UP(a,n,LIS_NOTDOWN);非下降*/typedefintElementType;#defineLIS_UP0/严格上升#defineLIS_NOTDOWN1/非下降intLIS(ElementType*a,intn,intflag)inti;ElementType*d=newElementTypen+1;for(i=0;i=n;i+)di=0;intlen=1;d1=a1;for(i=2;i=n;i+)intl=0,h=len;if(flag=LIS_NOTDOWN)if(dlenlen)len+;deleted;returnlen;最长公共子序列向最长递增子序列退化:设有序列A,B。记序列A中各个元素在B中的位子(降序排列),然后按在A中的位置依次列出然后求A
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 网瘾安全教育
- 株洲师范高等专科学校《大数据实践》2023-2024学年第二学期期末试卷
- 新疆职业大学《生物课程标准与教材分析》2023-2024学年第二学期期末试卷
- 中国矿业大学徐海学院《食品质量与安全专业导论》2023-2024学年第一学期期末试卷
- 山东建筑大学《旅行社管理实验》2023-2024学年第二学期期末试卷
- 山西能源学院《英语视听说Ⅱ》2023-2024学年第一学期期末试卷
- 《商品与货币交换演变》课件
- 人工清理田面施工方案
- 漳州职业技术学院《消化与呼吸系统医学教程》2023-2024学年第二学期期末试卷
- 2025至2031年中国家用空气清新器行业投资前景及策略咨询研究报告
- 阅读提取信息课件
- 医保业务培训大纲
- 中国职工保险互助会陕西办事处招聘考试真题2024
- 商铺施工方案
- 北师大版2024-2025学年度第二学期一年级数学期中检测(含答案)
- 第10课 养成遵纪守法好习惯
- 2025修订版《保障中小企业款项支付条例》解读学习课件
- 江苏省2024年中职职教高考文化统考烹饪专业综合理论真题试卷
- 市政工程施工部署与资源配置计划
- 《变态反应性皮肤病》课件
- (2024年)知识产权全套课件(完整)
评论
0/150
提交评论