• 数塔取数问题


    题目六、数塔取数问题

    一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值。

    每次只能走到下一层相邻的数上,例如从第3层的6向下走,只能走到第4层的2或9上。

    5

    8 4

    3 6 9

    7 2 9 5

    例子中的最优方案是:5 + 8 + 6 + 9 = 28

    Input

    第1行:N,N为数塔的高度。(2 <= N <= 500)

    第2 - N + 1行:每行包括1层数塔的数字,第2行1个数,第3行2个数......第k+1行k个数。数与数之间用空格分隔(0 <= A[i] <= 10^5) 。

    Output

    输出最大值

    输入示例

    4

    5

    8 4

    3 6 9

    7 2 9 5 

    7

    7

    8 4

    3 6 9

    7 2 9 5

    12 33 4 5 66

    23 4 344 55 33 12

    23 23 44 90 78 77 99

    输出示例

    28

    492

    解题思路:

    这题的解题思路第一个大概就是暴力了吧 ==,先来讲讲暴力的思路。就开一个二维数组存储数字塔,我就从塔顶枚举每一条可能的路径,类似于二叉数,要枚举的路径在2^n级别,考虑n = 500的情况,大概也就10^150的数量级,真是妥妥的超时。

    所以就要第二种方法,动态规划。在开一个储存数字塔的二维数组f的同时,也开启一个同样大小的数组dp[][],dp[i][j]表示第i行第j列的元素到底层的最短距离。dp[i][j] = max(dp[ i + 1 ][ j ] , dp[ i + 1 ][ j + 1] ) + f[ i ][ j ],f[i][j]为数字塔的具体元素。时间复杂度就从指数级降到了平方级。

    代码:

    #include <cstdio>
    #include <algorithm>
    #define MAXN  510
    using namespace std;
    int f[MAXN][MAXN], dp[MAXN][MAXN];// 数字塔数组和dp数组 
    int main() {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {// 循环输入数字塔 
            for (int j = 1; j <= i; j++) {
                scanf("%d", &f[i][j]);
            }
        }
        for (int j = 1; j <=n; j++) {
            dp[n][j] = f[n][j]; // dp数组最底层的元素和数组塔最底层的元素相同,自己到自己的数字之和当然是本身咯 
        }
        for (int i = n - 1; i >= 1; i--) {
            for (int j = 1; j <= i; j++) {
                dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + f[i][j]; //状态转移方程 
            }
        }
        
        printf("%d\n", dp[1][1]); //dp[1][1]就是从顶层到底层的最大距离,即为所求 
        return 0;
    }
  • 相关阅读:
    11
    不错的Spring学习笔记(转)
    面相对象
    Shiro框架学习
    浅谈重载与重写
    二叉树的Java实现及特点总结
    Spring注解及作用
    java中String与StringBuilder的区别
    Java String, StringBuffer和StringBuilder实例
    Docker Mysql主从同步配置搭建
  • 原文地址:https://www.cnblogs.com/MATLABlearning001/p/5396979.html
Copyright © 2020-2023  润新知