方法1【二维dp】
1、dp[i][j]经过(i,j)点的最短路径
2、边界只有一种递推,如下边2个if
3、中间dp[i][j] = min(dp[i-1][[j], dp[i-1][j-1]) + triangle[i][j]
【即2条路径选一条最短的来】
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int m = triangle.size();
int n = triangle[0].size();
int dp[200][300];
dp[0][0] = triangle[0][0];
for(int i = 1; i < m; i++) {
for(int j = 0; j < (int)triangle[i].size(); j++) {
if ((j - 1) < 0) {
dp[i][j] = dp[i-1][j] + triangle[i][j];
} else
if (j == (int)triangle[i].size() - 1) {
dp[i][j] = dp[i-1][j-1] + triangle[i][j];
} else {
dp[i][j] = min(dp[i-1][j], dp[i-1][j-1]) + triangle[i][j];
}
}
}
int ans = INT_MAX;
for(int j = 0; j < (int)triangle[m-1].size(); j++) {
ans = min(ans,dp[m-1][j]);
}
return ans;
}
};
方法2【一维dp】
1、倒着推上来
2、dp[j]表示到该列前一层为止的最短路径
3、递推:下边一行有2列能到该点,那就是j和j+1,选短的
4、其实是靠外循环降维,外层行数边了(row–)就等价于dp[j]换成新的row的列的路径了,因为只需要下边一层的数据,下下层等不用保存,然后在未更新前,dp[j]保存的就是下一层的数据
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int dp[200];// 列
int m = triangle.size();
for(int col = 0; col < (int)triangle[m-1].size(); col++) {
dp[col] = triangle[m-1][col];
}
for(int row = m - 2; row >= 0; row--) {
for(int j = 0; j < (int)triangle[row].size(); j++) {
dp[j] = min(dp[j], dp[j+1]) + triangle[row][j];
}
}
return dp[0];
}
};