📅  最后修改于: 2023-12-03 14:54:52.187000             🧑  作者: Mango
数字三角形是一种常见的算法题,也是动态规划的典型问题之一。它的任务就是在一个数字三角形中寻找一条从顶部到底部的路径,使得路径经过的数字之和最大。
给定一个数字三角形triangle
,其行数为n
,其中每行有i
个数字。设计一个算法,计算从三角形顶部到底部的一条路径,使该路径经过的数字之和最大。
下面是一个数字三角形的例子:
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
在这个例子中,最优路径的数字之和为7 + 8 + 0 + 7 + 5 = 27
。
为了寻找数字三角形中最优的路径,我们可以使用动态规划算法。具体来说,我们可以定义一个动态规划数组dp
,其中dp[i][j]
表示从三角形顶部到(i,j)
位置的最优路径的数字之和。根据题目的性质,显然有,
$$ dp[i][j] = triangle[i][j] + \max{dp[i-1][j-1], dp[i-1][j]} $$
这意味着,从(i-1,j-1)
或(i-1,j)
两个位置中任意一个位置转移而来,我们只需要在这两个结果中选择较大的一个,并加上当前位置的数字,就得到了从三角形顶部到当前位置的最优路径的数字之和。
最终答案即为dp[n-1]
数组中的最大值。
下面是一个使用C++语言实现数字三角形算法的代码。代码中,我们使用一个二维数组triangle
存储三角形中的数字,并使用一个二维数组dp
来计算每个位置的最优解。
#include <iostream>
#include <vector>
using namespace std;
int maxPathSum(vector<vector<int>>& triangle) {
int n = triangle.size();
vector<vector<int>> dp(n, vector<int>(n, 0));
dp[0][0] = triangle[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] + triangle[i][j];
} else if (j == i) {
dp[i][j] = dp[i-1][j-1] + triangle[i][j];
} else {
dp[i][j] = max(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j];
}
}
}
int ans = dp[n-1][0];
for (int i = 1; i < n; i++) {
ans = max(ans, dp[n-1][i]);
}
return ans;
}
int main() {
vector<vector<int>> triangle = {
{7},
{3, 8},
{8, 1, 0},
{2, 7, 4, 4},
{4, 5, 2, 6, 5},
};
cout << maxPathSum(triangle) << endl;
// Output: 27
return 0;
}
数字三角形问题不仅是一个典型的算法题,同时也是动态规划的重要应用之一。要解决这个问题,我们需要使用动态规划数组来存储每个位置的最优解,并按照转移方程来计算每个位置的最优解。在具体实现时,我们只需要编写一个双重循环来依次计算每个位置的最优解即可。