📜  数字三角形c++(1)

📅  最后修改于: 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;
}
总结

数字三角形问题不仅是一个典型的算法题,同时也是动态规划的重要应用之一。要解决这个问题,我们需要使用动态规划数组来存储每个位置的最优解,并按照转移方程来计算每个位置的最优解。在具体实现时,我们只需要编写一个双重循环来依次计算每个位置的最优解即可。