参考:经典算法——数字三角形的三种解题方法:递推、记忆化搜索、动态规划
解法一:
//递推方法
/*
* 思路整理:
* 首先找出递推公式:
* arr[i][j] = arr[i][j] + max(arr[i+1][j],arr[i+1][j+1])
*
* 递推从下往上,一直计算到最上面的时候刚好是最大值
*
* 数字三角形。如下图所示的数字三角形,从三角形的顶部到底部有很多条不同的路径。
* 对于每条路径,把路径上面的数加起来可以得到一个和,和最大的路径称为最佳路径。
* 编写一个程序求出最佳路径上的数字之和。
* 【注意:路径上的每一步只能从一个数走到下一层上和它最近的左边的数或者右边的数。】
* 7
* 3 8
* 8 1 2
* 2 7 4 4
* 4 5 2 6 5
*
*/
public class Triangle_recursion {
public static void main(String[] args) {
int[][] arr = {
{1},
{2, 3},
{4, 5, 6},
{7, 8, 9, 2}
};
int row = arr.length;
solution1(arr, row);
}
private static void solution1(int[][] arr, int row) {
int k = row - 1; //数组下标最大 n-1
while (k > 0) { //k=0时不用计算
for (int i = 0; i <= k - 1; i++) {
arr[k - 1][i] += Math.max(arr[k][i], arr[k][i + 1]);
}
k--;
}
System.out.println(arr[0][0]);
System.out.println("逐层计算求和后的数组是:");
for (int i = 0; i < arr.length; i++) {
int[] ints = arr[i];
for (int j = 0; j < ints.length; j++) {
System.out.print(ints[j] + " ");
}
System.out.println();
}
}
}
解法二
/* 动态规划方法 核心思想:将问题拆分为若干个子问题
*
* 思路整理: 找出重叠的子问题
* 首先写出状态转移方程:
* arr[i][j] = arr[i][j] + max(arr[i+1][j],arr[i+1][j+1])
*
* 必须由上往下计算,计算得最后一排的数值成为所有路径的最大值,
* 最后遍历最后一行,找出最大值中的最大值,即得所解
*
*/
public class Triangle_DynamicProgramming {
public static void main(String[] args) {
int[][] arr = {
{1},
{2, 3},
{4, 5, 6},
{7, 8, 9, 2}
};
int row = arr.length;
solution2(arr, row);
}
private static void solution2(int[][] arr, int row) {
// 利用动态规划特点:
// 下一层的结果不影响上一层的结果,所以可以直接计算了将数组覆盖,不需要在new一个新的空间
// 数组第一层不变
for (int i = 1; i < row; i++) {
for (int j = 0; j <= i; j++) { // 第二维
if (j == 0) // 第一个数
arr[i][j] += arr[i - 1][0];
else if (j == i) // 最后一个数
arr[i][j] += arr[i - 1][j - 1];
else // 中间的所有数
arr[i][j] += Math.max(arr[i - 1][j - 1], arr[i - 1][j]);
}
}
//比较最后一行大小
int max = arr[row - 1][0];
for (int i = 0; i < row; i++) {
if (max < arr[row - 1][i])
max = arr[row - 1][i];
}
System.out.println(max);
System.out.println("逐层计算求和后的数组是:");
for (int i = 0; i < arr.length; i++) {
int[] ints = arr[i];
for (int j = 0; j < ints.length; j++) {
System.out.print(ints[j] + " ");
}
System.out.println();
}
}
}