数字三角形
给定一个数字三角形,找到从顶部到底部的最小路径和.每一步可以移动到下面一行的相邻数字上。
样例 1:
输入:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
输出:
11
解释: 从顶到底部的最小路径和为11 ( 2 + 3 + 5 + 1 = 11)
样例 2:
输入:
[
[2],
[3,2],
[6,5,7],
[4,4,8,1]
]
输出:
12
解释: 从顶到底部的最小路径和为12 ( 2 + 2 + 7 + 1 = 12)
解答:
取表A[m][n]
定义dp[i][j]为从顶点到[i][j]点的最小路径和,由从上往下仅可往下或右下走,
故:
dp[i][j] = min(dp[i-1][j] + A[i][j], dp[i-1][j-1]+A[i][j]) {0<=i<=m,0<=j<=n};
class Solution {
public:
/**
* @param triangle: a list of lists of integers
* @return: An integer, minimum path sum
*/
int minimumTotal(vector<vector<int>> &triangle) {
// write your code here
/*
取表A[m][n]
定义dp[i][j]为从顶点到[i][j]点的最小路径和,由从上网下仅可往下或右下走,
故:
dp[i][j] = min(dp[i-1][j] + A[i][j], dp[i-1][j-1]+A[i][j]) {0<=i<=m,0<=j<=n};
*/
if(triangle.empty()){
return 0;
}
int m = triangle.size() + 1;
int n = 0;
for (int i = 0; i < triangle.size(); i++) {
n = max(n, (int)triangle[i].size());
}
n += 1;
int ** dp = new int*[m];
for (int i = 0; i < m; i++) {
dp[i] = new int[n];
for (int j = 0; j < n; j++) {
dp[i][j] = 0x0fffffff;
}
}
for (int i = 1; i < m; i++) {
dp[i][0] = 0x0fffffff;
}
for (int i = 0; i < n; i++) {
dp[0][i] = 0;
}
// 行
for (int i = 1; i < m; i++) {
// 列
for (int j = 1; j <= triangle[i-1].size(); j++) {
dp[i][j] = min(dp[i-1][j] + triangle[i-1][j-1], dp[i-1][j-1]+triangle[i-1][j-1]);
}
}
int nMin = 0x7fffffff;
for (int i = 1; i < n; i++) {
nMin = min(nMin, dp[m-1][i]);
}
for (int i = 0; i < m; i++) {
delete[] dp[i];
}
delete[] dp;
return nMin;
}
};