问题描述:从数塔的顶层出发,在每一个结点可以选择向左走或向右走,一直走到最底层,要求找出一条路径,使得路径上的数值和最大。
示例:
思想:
6.3 数塔问题
package main.com.edu.shengda.suanfa;
import java.util.Scanner;
public class ShuTa {
public static void tpWalk(int[][] tower) {
//定义一个 tower.length 层的数组
int[][] dpTower = new int[tower.length][];
//把最底层地址赋值给dpTower 打印两个数组发现地址一样
dpTower[tower.length - 1] = tower[tower.length-1];
//从倒数第二层循环
for(int i = tower.length - 2;i >= 0;i--) {
//把前i层的数据拷贝赋给dpTower 打印两个数组发现地址不一样
//tower[i][I@30f39991
//dpTower[i][I@452b3a41
dpTower[i] = tower[i].clone();
//找出每一层的较大的数并加到上一层
for(int j = 0;j<dpTower[i].length;j++) {
//如果最后一层的第一个 大于 第二个
if(dpTower[i+1][j] > dpTower[i+1][j+1])
//倒数第二层的 第一个就是,最后一层比较大的那个,再加上自己
// 如此循环直到本层结束回到第一个for循环层数往上移动
dpTower[i][j] += dpTower[i+1][j];
else {
dpTower[i][j] += dpTower[i+1][j+1];
}
}
}
System.out.println("最优路径长度:" + dpTower[0][0]);
System.out.println("最优路径:");
int j=0;//路径节点
for(int i = 0;i<dpTower.length-1;i++) {
//dpTower[i].length-1 整个数组最大路径和
if(j<dpTower[i].length-1 && dpTower[i][j] < dpTower[i][j+1])
//谁大就输出谁
j =j+1;
//第一次循环直接输出
System.out.print(tower[i][j] + "->");
}
//解决最后一层的问题
//dpTower[dpTower.length-1].length-1 最后一层的长度
//同理 判断 如果小于的话 谁大就输出谁 j =j+1;
if(j<dpTower[dpTower.length-1].length-1 && dpTower[dpTower.length-1][j] < dpTower[dpTower.length-1][j+1])
j =j+1;
//否则直接输出
System.out.println(tower[dpTower.length-1][j]);
}
public static void main(String[] args) {
System.out.println("请输入数塔的层数");
创建对象
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] tower = new int[n][];
//动态的为每一个一维数组分配空间
for (int i = 0; i < n; i++) {
tower[i] = new int[i + 1];
//输入每一个一维数组的元素
System.out.println("请输入第"+ i + "层的数据");
for (int j = 0; j < i + 1; j++) {
tower[i][j] = sc.nextInt();
}
}
//打印数组
for(int i = 0;i<tower.length;i++) {
for(int j = 0;j<tower[i].length-1;j++) {
System.out.print(tower[i][j] + " ");}
System.out.println(tower[i][tower[i].length-1]);
}
tpWalk(tower);
}
}