• ACwing 898


    给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大。

            7
          3   8
        8   1   0
      2   7   4   4
    4   5   2   6   5
    

    输入格式

    第一行包含整数n,表示数字三角形的层数。

    接下来n行,每行包含若干整数,其中第 i 行表示数字三角形第 i 层包含的整数。

    输出格式

    输出一个整数,表示最大的路径数字和。

    数据范围

    1 ≤ n ≤ 500,
    −10000 ≤ 三角形中的整数 ≤ 10000

    输入样例:

    5
    7
    3 8
    8 1 0
    2 7 4 4
    4 5 2 6 5

    输出样例:

    30

    题目大意:

    给出一个数字三角形,从上往下,每一个节点都可以移动至距离最近的左下或右下节点,你需要选择一条路,使得路径上的数字之和最大。

    解题思路:

    dp经典问题之数字三角形模型,处理动态规划问题从两方面入手,状态表示和状态计算。

    • 状态表示:用二维去表示状态,f (i, j) 表示的集合是起点走到i,j点的所有走法的路径和,而属性是最大值,总结一下,f (i, j) 表示从起点走到i, j 时的路径和的最大值。
    • 状态计算: 集合的划分,这要看f (i, j) 可以从哪些集合转移过来,结合题意,则该点可以从左上走下来,也可以从右上走下来,所以二者取最大值即可得到状态转移方程:f[i][j] = max(f[i - 1][j], f[i][j - 1]) + f[i][j]

    Code:

    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 510;
    
    int f[N][N];
    int n;
    
    int main()
    {
        cin >> n;
        
        for (int i = 1; i <= n; i ++)
            for (int j = 1; j <= i; j ++)
                cin >> f[i][j];
        
        for (int i = 2; i <= n; i ++)
            for (int j = 1; j <= i; j ++)
                if (j == 1) f[i][j] = f[i - 1][j] + f[i][j];//特判一下,因为等于1和n的时候只能从一种集合转移过来
                else if (j == i) f[i][j] = f[i - 1][j - 1] + f[i][j];
                else f[i][j] = max(f[i - 1][j], f[i - 1][j - 1]) + f[i][j];
    
        int res = 0;
        for (int i = 1; i <= n; i ++) res = max(res, f[n][i]);
        
        cout << res << endl;
        
        return 0;
    }
    
  • 相关阅读:
    突然又想起了这首诗
    安装使用Androidx86打造快速流畅的Aandroid开发环境!
    解决电脑没插网线虚拟机无法桥接到主机
    使用WordPress更新通知服务,让搜索引擎知道你更新了,加快收录。
    php+apache+mysql环境配置时apache服务不能开启的解决
    WordPress备份的七种办法
    怎么在网站中正确使用JQuery代码
    如何让自己的博客在各搜索引擎中被搜索出来与快速收录
    轻松查看文件被哪个进程使用
    解密QQ非会员漫游聊天记录
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294133.html
Copyright © 2020-2023  润新知