如果要求出 dp[i][j],那么一定要先求出它的两个子问题:
①从位置(i+1, j) 到达最底层的最大和 dp[i+1][j];
②从位置(i+1, j+1) 到达最底层的最大和 dp[i+1][j+1]。
状态转移方程
把状态 dp[i][j] 转移为 dp[i+1][j] 和 dp[i+1][j+1]
边界:最后一层的dp值总是等于元素本身。
从这些边界出发,通过状态转移方程扩散到整个 dp数组。
数塔问题
// 03.16 10:00-12:00
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1000;
int f[maxn][maxn], dp[maxn][maxn];
int main() {
freopen("input.txt", "r", stdin);
// 输入数塔
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
scanf("%d", &f[i][j]);
}
}
// 边界
for (int j = 1; j <= n; j++) {
dp[n][j] = f[n][j];
}
// 从倒数第二层(n-1)层,往上计算 dp[i][j]
for (int i = n - 1; i >= 1; i--) {
for (int j = 1; j <= i; j++) {
dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + f[i][j];
}
}
printf("%d\n", dp[1][1]);
return 0;
}