動態規劃--最長公共子序列(Java)
阿新 • • 發佈:2018-12-11
0.問題描述
給出兩個序列X,Y,求出他們的最長公共子序列及長度
1.分解最優解的結構
(1)若Xm =Yn ,且 Zk =Xm =Yn , 那麼 Zk-1 是 Xm-1 和 Yn-1 的最長公共子序列 (2)若Xm ≠ Yn ,且 Zk ≠ Xm , 那麼 Zk-1 是 Xm-1 和 Yn 的最長公共子序列 (3)若Xm ≠ Yn ,且 Zk ≠ Ym , 那麼 Zk-1 是 Xm 和 Yn-1 的最長公共子序列
2.建立遞迴關係
Ci,j記錄公共子序列的長度
0 i=0,j=0 Ci,j= Ci-1,j-1 +1 i>0, j>0 ; Xi =Yj max { Ci-1,j ,Ci,j-1 } i>0, j>0 ; Xi ≠Yj
3.計算最優值 && 4.構造最優解
public class lcs{ public static int lcsLength(int []x,int []y,int m,int n,int [][]c){ for(int i=0;i<=m;i++){c[i][0]=0;} for(int j=0;j<=n;j++){c[0][j]=0;} for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(x[i]==y[j]){ 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[m][n]; } public static void lcs(int []x,int i,int j,int [][]c){ if(i==0||j==0){ return; } if(c[i][j]==c[i-1][j-1]+1){ lcs(x,i-1,j-1,c); System.out.println(x[i-1]); } else if(c[i][j]==c[i-1][j]){ lcs(x,i-1,j,c); } else{ lcs(x,i,j-1,c); } } public static void main(String[] args){ int x[]={0,1,2,3,4,5}; int y[]={1,2,3,4}; int m=x.length-1; //6 int n=y.length-1; //5 int c[][]=new int[m+1][n+1]; int length=lcsLength(x,y,m,n,c); System.out.println("The length of lcs is: "+length); System.out.println("They are:"); lcs(x,m,n,c); } }