解題思路及代碼:
/*
算法概述:用動態規劃。設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];
}
還闊以哈哈哈