问题描述
给定一个nn层的金字塔,求一条从最高点到底层任意点的路径使得路径经过的数字之和最大。
注:每一步可以走到左下方的点也可以到达右下方的点。
思路
分为二种情况:
1 . 在三角形的两条腰上, 直接等于上一层列号小1的元素加上本身
2 . 在三角形中间,取上一层相邻的两个元素最大的那个加上本身
细节
三角形的下标从都是从1开始,这样相当于三角形边界围了一圈0。
这样一来,当 j == 1 时,f[i - 1][j] == 0。因为在数字金字塔所有数字都是正数的情况下,max函数一定不会选择用f[i - 1][j]来转移
i == j 的情况同理。
代码
#include <bits/stdc++.h>
#define N 1005
#define M 110
using namespace std;
int n;
int a[N][N], f[N][N];
int main() {
// 输入
cin >> n;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= i; ++j)
cin >> a[i][j];
// 动态规划过程
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= i; ++j)
f[i][j] = max(f[i - 1][j - 1], f[i - 1][j]) + a[i][j];
// 此处没有讨论 j == 1 和 i == j 的情况
// 是因为当 j == 1 时,f[i - 1][j] == 0
// 是因为在数字金字塔所有数字都是正数的情况下
// max函数一定不会选择用f[i - 1][j]来转移
// i == j 的情况同理
// 输出
int ans = 0;
for (int i = 1; i <= n; ++i) ans = max(ans, f[n][i]); // 求第n行的最大值
cout << ans << endl;
return 0;
}
参考: 青舟智学