动态规划解决数塔问题

一、题目
如图所示,将一些数字排成数塔的形状,其中第一层有一个数字,第二层有两个数字.……第n层有n个数子。现在要从第一层走到第n层,每次只能走向下一层的接连两个数字的其中一个,问:最后将路径上所有数字相加后得到的和最大是多少?
这里写图片描述
二、动态规划解法
设ele[i][j]表示第i层的第j个元素,max[i][j]表示从第i层第j个元素出发的到达最底层的所有路径中能得到的最大和。那么max[i][j]的值就是从max[i+1][j]和max[i+1][j+1]取最大值再加上ele[i][j],所以的到递推公式:max[i][j] = max{max[i+1][j],max[i+1][j+1]}+ele[i][j]。对于最后一层元素,max[n-1][j] = ele[n-1][j]。最终只要从最底层递推到第一层,max[0][0]就是所求的结果。
三、代码(Java)

public static int tower(int n,int[][] ele) throws Exception{
        if(n<0||ele==null){
            throw new Exception("参数错误!");
        }
        int[][] max = new int[n][n];//记录以当前元素开始的最大路径和
        //最后一层,max[n][i]和ele[n][i]相等
        for(int i=0;i<n;i++){
            max[n-1][i] = ele[n-1][i];
        }
        //开始递推,直到最顶层的元素
        for(int j=n-2;j>=0;j--){
            for(int k=0;k<=j;k++){
                max[j][k] = Math.max(max[j+1][k],max[j+1][k+1])+ele[j][k];
            }
        }
        return max[0][0];
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
数塔问题是一个经典的动态规划问题,它的描述如下:给定一个由n行数字组成的数塔,如下图所示,从顶部出发,在每个节点可以选择向左或向右走,依次走到底部,使得所经过的数字之和最大。每次只能走到下一行相邻的两个节点。 ``` 5 8 4 3 6 9 7 2 9 5 2 8 4 1 7 ``` 使用动态规划思想,可以得到以下解题步骤: 1. 定义状态:设f[i][j]表示从第i行第j个数字开始走到最后一行所能得到的最大数字之和。 2. 状态转移方程:对于第i行第j个数字,其下一行相邻的数字为f[i+1][j]和f[i+1][j+1],那么状态转移方程为f[i][j] = max(f[i+1][j], f[i+1][j+1]) + a[i][j],其中a[i][j]表示第i行第j个数字的值。 3. 初始状态:对于最后一行的每个数字,其状态值为其自身的值,即f[n][j] = a[n][j]。 4. 求解目标:最终的目标是求解f[1][1],即从顶部开始走到底部所能得到的最大数字之和。 根据上述步骤,可以使用以下的动态规划代码实现数塔问题的求解: ```python # 假设a为一个n行n列的二维数组,表示数塔的数字 def max_sum(a): n = len(a) f = [[0] * n for _ in range(n)] # 初始化最后一行状态值 for j in range(n): f[n-1][j] = a[n-1][j] # 从倒数第二行开始逐行计算状态 for i in range(n-2, -1, -1): for j in range(i+1): f[i][j] = max(f[i+1][j], f[i+1][j+1]) + a[i][j] # 返回顶部节点的状态值 return f[0][0] ``` 以上代码的时间复杂度为O(n^2),空间复杂度为O(n^2),可以通过数塔问题的所有测试用例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AE86Jag

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值