解题思路及代码:
/*
算法概述:用动态规划。设f[i][j]表示从三角形顶部到(i,j)这个位置的最小路径和
状态转移方程:f[i][j] = tri[i][j] + min{ f[i - 1][j - 1], f[i - 1][j] }
*/
#define MAX_SIZE 200
#include<string.h>
int minimumTotal(int** triangle, int triangleSize, int* triangleColSize){
int ans = 0;
int i = 0, j = 0;
int f[MAX_SIZE][MAX_SIZE];
int choose[MAX_SIZE][MAX_SIZE];// 某个位置的最佳走法,0代表向左走,1代表向右走
memset(f, 0, sizeof(f));
memset(choose, 0, sizeof(choose));
for (i = 0; i < triangleSize; i++)// 最后一层的最小路径就是当前位置的值
f[triangleSize - 1][i] = triangle[triangleSize - 1][i];
for (i = triangleSize - 2; i >= 0; i--) {// 从下往上逆推
for (j = 0; j <= i; j++) {
if (f[i + 1][j] > f[i + 1][j + 1]) {
choose[i][j] = 1;// 向右走
f[i][j] = triangle[i][j] + f[i + 1][j + 1];
}
else {
choose[i][j] = 0;// 向左走
f[i][j] = triangle[i][j] + f[i + 1][j];
}
}
}
j = 0;
for (i = 0; i < triangleSize; i++) {// 累加结果
ans += triangle[i][j];
if (choose[i][j] == 1)
j++;
}
return ans;
}
题目提示可以用O(n)的空间复杂度实现,于是试了试:
优化代码:
/*
算法概述:用动态规划。设f[i][j]表示从三角形顶部到(i,j)这个位置的最小路径和
状态转移方程:f[i][j] = tri[i][j] + min{ f[i - 1][j - 1], f[i - 1][j] }
用choose[i][j]保存每个位置的走法
优化:不要f[][]和choose这两个辅助空间,直接在triangle上面操作即可
状态转移方程:triangle[i][j] = triangle[i][j] + min{ triangle[i - 1][j - 1], triangle[i - 1][j] }
由于某一层的数只需要为它的上一层提供服务,所以这个方案是可行的
最后直接返回triangle[0][0]即可
*/
int minimumTotal(int** triangle, int triangleSize, int* triangleColSize){
int i = 0, j = 0;
for (i = triangleSize - 2; i >= 0; i--) {// 从下往上逆推
for (j = 0; j <= i; j++) {
if (triangle[i + 1][j] > triangle[i + 1][j + 1])
triangle[i][j] = triangle[i][j] + triangle[i + 1][j + 1];// 选右边
else
triangle[i][j] = triangle[i][j] + triangle[i + 1][j];// 选左边
}
}
return triangle[0][0];
}
还阔以哈哈哈