描述
给定一个三角形 triangle ,找出自顶向下的最小路径和。
每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。
分析
从上到下的动态规划不如从下向上简单,考虑的边界条件少。
从下向上的动态规划
class Solution {
/*
暴力解法给一个数组,有多少子序列的和等于给定值。
动态规划(有创建二维数组)是从底向上计算的
dp[i][j]表示第i至最底层的最小路径和加上triangle[i][j].
本题求三角形的最小路径和等同于求dp[0][0]
初始化数据:triangle的最后一行。
动态转移方程:dp[i][j]=dp[i+1][j]+dp[i+1][j+1]+triangle[i][j]
*/
public int minimumTotal(List<List<Integer>> triangle) {
int row= triangle.size();
int col=triangle.get(row-1).size();
int [][]dp=new int [row][col];
for(int i=row-1;i>-1;i--){
for(int j=0;j<triangle.get(i).size();j++){
if(i==row-1){
dp[i][j]=triangle.get(row-1).get(j);
continue;
}
dp[i][j]=Math.min(dp[i+1][j],dp[i+1][j+1])+triangle.get(i).get(j);
}
}
return dp[0][0];
}
}
从上到下的动态规划
import java.util.*;
public class Solution {
public int minTrace (int[][] triangle) {
int m = triangle.length;
if(m == 1){
return triangle[0][0];
}
int n = triangle[m-1].length;
int[][] dp = new int[m][n];
dp[0][0] = triangle[0][0];
int ans = Integer.MAX_VALUE;
for(int i = 1; i < m; i++){
for(int j = 0; j <= i; j++){
int a = j == 0 ? Integer.MAX_VALUE : dp[i-1][j-1];
int b = j == i ? Integer.MAX_VALUE : dp[i-1][j];
dp[i][j] = Math.min(a,b) + triangle[i][j];
if(i == m-1){
ans = Math.min(ans,dp[i][j]);
}
}
}
return ans;
}
}