以所经过的权值之和最大值为例进行说明。
行进的过程中,每次只有两种选择:向左或向右。一个有n层的数字三角形的完整路径有2n条,所以当n比较大的时候,搜索全部路径,从中找出最大值,效率较低。
采用动态规划方法实现。
用d(i,j)表示从位置(i,j)出发时得到的最大值(包括位置(i,j)本身),可以写出最大值的递归方程:
d(i,j)=a(i,j)+max{d(i+1,j),d(i+1,j+1)}
由于递归方程中包含了重复子问题,直接采用递归方程求解, 效率较低。采用动态规划的方法,用一张二维表记录中间过程的值,可以把时间效率提高到n2。
package 实验三;
public class 数字三角形 {
public static void main(String[] args) {
D d=new D();
d.Way();
d.show1();
d.show2();
d.show3();
}
}
class D{
int [][] s= {{1},{2,3},{10,8,7},{1,6,12,9}}; //三角形数据
int n=s.length;
int [][] max=new int[n][n]; //记录每一层最大数据
void Way() {
for(int i=0;i<n;i++) {
max[n-1][i]=s[n-1][i]; //初始化,最下面一层的max数组就是三角形最下面一层的值
}
for(int i=n-2;i>=0;i--) { //从倒数第二层向上计算
for(int j=0;j<=i;j++) { //计算第 i 层的每一个点的 max[][]
int one=max[i+1][j]; //要么向下一层上和它最近的左边走
int two=max[i+1][j+1]; //要么向下一层上和它最近的右边走
if(one>two) {
max[i][j]=s[i][j]+one;
}
else {
max[i][j]=s[i][j]+two;
}
}
}
}
void show1() {
for(int i=0;i<n;i++) {
for(int j=0;j<=i;j++) {
System.out.printf("%-3d",s[i][j]);
}
System.out.println();
}
}
void show2() {
for(int i=0;i<n;i++) {
for(int j=0;j<=i;j++) {
System.out.printf("%-3d",max[i][j]);
}
System.out.println();
}
}
void show3() {
int i=0,j=0;
while(i<n) {
if(i==0)
System.out.print("路径为:"+s[0][0]+" ");
else if(max[i][j]>max[i][j+1]) {
System.out.print(s[i][j]+" ");
}
else {
System.out.print(s[i][j+1]+" ");
j=j+1;
}
i++;
}
}
}