2919: 【例67.3】 数字金字塔

内存限制:64 MB 时间限制:1.000 S
评测方式:文本比较 命题人:
提交:14 解决:11

题目描述

观察下面的数字金字塔。写一个程序查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以从当前点走到左下方的点也可以到达右下方的点:
                                      13
                            11                  8
                   12                 7                  26
         6                 14                 15                8
12                 7                  13                 24              11

$1≤x≤20,1≤y≤20,x< z≤50$。

输入

第一个行包含$R$($1≤R ≤1000$),表示行的数目。后面每行为这个数字金字塔特定行包含的整数。
所有的被供应的整数是非负的且不大于$100$。

输出

单独的一行,包含那个可能得到的最大的和。

样例输入 复制

5
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11

样例输出 复制

86

提示


【分析】从递推的思想出发,当从顶层沿着某条路径从第i层向第i+1层前进时,我们的选择一定是沿其下两条可行路径中最大数字的方向前进,为此,我们可以采用逆推的方法,让a[i][j]存放从i,j出发到达第n层的最大值,则a[i][j]=max(a[i][j]+a[i+1][j],a[i][j]+a[i+1][j+1]),依次类推,a[1][1]中即为所求的最大总和。

#include<iostream>

using namespace std;
int main() {
    int n, i, j, a[1001][1001];
    cin >> n;
    for (i = 1; i <= n; i++)
        for (j = 1; j <= i; j++)
            cin >> a[i][j];
    for (i = n - 1; i >= 1; i--)
        for (j = 1; j <= i; j++)
            a[i][j] = max(a[i][j] + a[i + 1][j], a[i][j] + a[i + 1] + a[j + 1]);
    cout << a[1][1];
    return 0;
}

#include<iostream>

using namespace std;
int main() {
    int n, i, j, a[1001][1001];
    cin >> n;
    for (i = 1; i <= n; i++)
        for (j = 1; j <= i; j++)
            cin >> a[i][j];
    for (i = n - 1; i >= 1; i--)
        for (j = 1; j <= i; j++)
            if (a[i + 1][j] >= a[i + 1][j + 1])
                a[i][j] += a[i + 1][j];
            else a[i][j] += a[i + 1][j + 1];
    cout << a[1][1];
    return 0;
}