题目描述 考虑在下面被显示的数字金字塔。 写一个程序来计算从最高点开始在底部任意处结束的路径经过数字的和的最大值。 每一步可以走到左下方的点也可以到达右下方的点。 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 在上面的样例中,从7 到 3 到 8 到 7 到 5 的路径产生了最大和:30。为了方便描述把数字金字塔描述为: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 输入 第一行,一个正整数N。表示数字金字塔的层数。(1<=N<=50) 接下来N行,第i行由空格隔开的i个正整数,每个正整数不超过100。构成此数字金字塔。 输出 一行,一个正整数,表示路径和的最大值。 样例输入 Copy 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 样例输出 Copy 30
时间: 2024-04-08 13:34:45 浏览: 104
这个问题可以使用动态规划来解决。我们可以定义一个二维数组 `dp`,其中 `dp[i][j]` 表示从最高点到第 `i` 行第 `j` 列的位置的路径经过数字的和的最大值。
根据动态规划的思想,我们可以通过计算之前的状态来计算当前状态。对于每个位置 `(i, j)`,我们可以选择从上一行的 `(i-1, j-1)` 或者 `(i-1, j)` 这两个位置向下移动到达 `(i, j)`。因此,我们可以得到状态转移方程:
```
dp[i][j] = max(dp[i-1][j-1], dp[i-1][j]) + nums[i][j]
```
其中 `nums[i][j]` 表示数字金字塔中第 `i` 行第 `j` 列的数字。
最终的结果就是最后一行各个位置的最大值中的最大值。即:
```
maxSum = max(dp[N-1][0], dp[N-1][1], ..., dp[N-1][N-1])
```
下面是根据以上思路编写的代码:
```cpp
#include <iostream>
#include <algorithm>
using namespace std;
const int maxN = 50;
int main() {
int N;
cin >> N;
int nums[maxN][maxN];
for (int i = 0; i < N; i++) {
for (int j = 0; j <= i; j++) {
cin >> nums[i][j];
}
}
int dp[maxN][maxN] = {0};
dp[0][0] = nums[0][0];
for (int i = 1; i < N; i++) {
for (int j = 0; j <= i; j++) {
if (j == 0) {
dp[i][j] = dp[i-1][j] + nums[i][j];
} else if (j == i) {
dp[i][j] = dp[i-1][j-1] + nums[i][j];
} else {
dp[i][j] = max(dp[i-1][j-1], dp[i-1][j]) + nums[i][j];
}
}
}
int maxSum = 0;
for (int j = 0; j < N; j++) {
maxSum = max(maxSum, dp[N-1][j]);
}
cout << maxSum << endl;
return 0;
}
```
希望这个解决方案对你有帮助!如果你有任何问题,请随时提问。
阅读全文