//主体思想:
//如果a[i]=a[j],子序列必还有a[i],继续求解a[i-1]和b[j-1]的问题
//如果不相等,取a[i]和b[j-1],a[i-1]和b[j]较大的一个子序列
package LongestSubsequence;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class LS {
public static void main(String[] args) {
int a0_length,a1_length;
// TODO Auto-generated method stub
char[][] a=new char[2][100];
a=readFile("C:\\Users\\dell\\Desktop\\a.txt");
a0_length=a[0].length;
a1_length=a[1].length;
int m=a0_length;
int n=a1_length;
int[][] c=new int[m+1][n+1];
int[][] d=new int[m][n];
//System.out.println(c[][1].length);
value(d,c,a[0],a[1],a0_length,a1_length);
//System.out.println(d[0][0]+d[0][1]+d[0][2]);
printLongest(d,a[0],a0_length-1,a1_length-1);
}
//读取文件
public static char[][] readFile(String path){
char[][] c=new char[2][100];
try {
FileInputStream fis=new FileInputStream(path);
Scanner in=new Scanner(fis,"GBK");
c[0]=in.nextLine().toCharArray();
//System.out.println(c[0].length);//读取文件后长度是文件的长度
c[1]=in.nextLine().toCharArray();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("读取文件失败!");
}
return c;
}
//二维数组C中的数代表此时子序列长度,d记录这个值从何而来
//如果a[i]=b[j],子序列必还有c[i][j]+1,d[i][j]=0
//如果不相等,且a[i],b[j-1]的共同子序列较长,d[i][j]=1
//否则d[i][j]=-1
static //d用来记录子问题的状态,c记录长度
void value(int[][]d,int[][]c,char[] a,char[] b,int a_length,int b_length){
for(int i=0;i<a_length+1;i++){c[i][0]=0;}
for(int j=1;j<b_length+1;j++){c[0][j]=0;}
for(int i=0;i<a_length;i++){
for(int j=0;j<b_length;j++){
if(a[i]==b[j]){ c[i+1][j+1]=c[i][j]+1;d[i][j]=0;}
else if(c[i][j+1]<=c[i+1][j]){c[i+1][j+1]=c[i+1][j];d[i][j]=1;}
else{c[i+1][j+1]=c[i][j+1];d[i][j]=-1;}
}
}
}
//写出最长子序列
public static void printLongest(int[][]d,char[]a,int i,int j){
if(i==-1||j==-1){return;}
//System.out.println(i+" "+j);
if(d[i][j]==0){printLongest(d,a,i-1,j-1);System.out.print(a[i]);}
else if(d[i][j]==-1){printLongest(d,a,i-1,j); }
else{printLongest(d,a,i,j-1); }
}
}
此动态规划方案同样适用于0-1背包问题:
对于物品Xi有两种方案,放入或不放入