动态规划 最长公共子序列

来源:互联网 发布:网络用语大全及解释88 编辑:程序博客网 时间:2024/06/09 22:19

动态规划算法的基本思想是:将待求解的问题分解成若干个相互联系的子问题,先求解子问题,然后从这些子问题的解得到原问题的解;对于重复出现的子问题,只在第一次遇到的时候对它进行求解,并把答案保存起来,让以后再次遇到时直接引用答案,不必重新求解。动态规划算法将问题的解决方案视为一系列决策的结果,与贪婪算法不同的是,在贪婪算法中,每采用一次贪婪准则,便做出一个不可撤回的决策;而在动态规划算法中,还要考察每个最优决策序列中是否包含一个最优决策子序列,即问题是否具有最优子结构性质。

最长公共子序列:

最长公共自序列的问题也具有最优子结构的性质:X={x1,x2.......xm} Y={y1,y2,...yn},公共子序列为Z={z1,....zk}

1.若Xm=Yn,则xm=yn=zk,则Zk-1也是Xm-1,Yn-1的最长公共子序列

2,若Xm!=Yn,则xm!=zk,则Zk-1也是Xm-1,Yn的最长公共子序列

3.若Xm!=Yn,则yn!=zk,则Zk-1也是Xm,Yn-1的最长公共子序列


问题求解:

引进两个二维数组c[][]和b[][],c[][]表示最长公共自序列的长度,b[][]表示c[][]是怎么得到啦,以此搜索出最长的公共子序列字符串。

根据最优子结构,建立的递归关系公式为:



回溯输出的过程:


package com.liheng.algorithm;/** *  * @author Administrator * 求公共子序列 * 功能:用动态规划的方法,求最长公共子序列 */public class MaxLen {    final static int maxLen=100;public static void main(String[] args) {// TODO Auto-generated method stub//把数组都进行初始化char []x = {'a','b','c','b','d','a','b','c'};char []y = {'b','d','c','a','b','a','c'};int m,n;m = x.length;n= y.length;int  [][]c = new int[maxLen][maxLen];int  [][]b = new int [maxLen][maxLen];MaxLen ml = new MaxLen();ml.LcslLength(m, n, x, y, c, b);ml.printLCS(m,n,x,b);}void LcslLength(int m,int n,char x[],char y[],int c[][],int b[][]){int i,j;//把第0行和第0列都赋值为0for( i=0;i<=m;i++){c[i][0] =0;}for( j=0;j<=n;j++){c[0][i]=0;}//动态规划递归for(i=1;i<=m;i++){for(j=1;j<=n;j++){//如果是两个相同的字符if(x[i-1]==y[j-1]){c[i][j]=c[i-1][j-1]+1;b[i][j]=1;}else if(c[i-1][j]>=c[i][j-1]){ //表示两个字符不同c[i][j] = c[i-1][j];b[i][j] =2;}else{c[i][j] = c[i][j-1];}}}}void printLCS(int m,int n,char x[],int b[][]){//当字符创为0时,函数返回if(m==0||n==0){return;}//从后向前递归搜索if(b[m][n]==1){printLCS(m-1,n-1,x,b);System.out.print(x[m-1]+" ");}else if(b[m][n]==2){printLCS(m-1,n,x,b);}else{printLCS(m,n-1,x,b);}}}


源代码:java


0 0
原创粉丝点击