动态规划--数塔问题

题目要求

给定一个数塔,其存储形式为如下所示的下三角矩阵。在此数塔中,从顶部出发,在每一节点可以选择向下走还是向右走,一直走到底层。请找出一条路径,使路径上的数值和最大。

输入样例(数塔):

9

12  15

10   6    8

2    18   9    5

19   7    10   4    16

输出样例(最大路径和):

59

题目分析

用一句话解释动态规划就是 “记住你之前做过的事”,如果更准确些,其实是 “记住你之前得到的答案”。

对于该题目,我们可以自上到下分析,自下到上计算

就是说你从上面一直选最大的,使用贪心算法,是不对。因为我们不知道在某个节点的下一个节点更大或者更小。

所以我们可以从下往上找出一条最大路径,不停的更新最大值,直到第二层,我们就选择出了一天最大路径

以题目为例:

第五层的数据分别是   19   7    10   4    16

从第四层开始  :                     如果选择了2,在第五层的(19 ,7),必然要选择19

                             那么路径最大只能是  2—>19= 21;

                            如果选择了18,在第五层的(7,10),必然要选择10

                             那么路径最大只能是  18—>10= 28;

                            如果选择了9,在第五层的(10 ,4),必然要选择10

                             那么路径最大只能是  9—>10= 19;

                            如果选择了5,在第五层的(4 ,16),必然要选择16

                              那么路径最大只能是  5—>16= 21;


第三层  :                                如果选择了10,在第四层的(2 ,18),必然要选择18(28>21)

                             那么路径最大只能是  10—>18—>10= 38;

                                           如果选择了6,在第四层的(18,9),必然要选择18(28>19)

                             那么路径最大只能是  6—>18—>10= 34;

                                    如果选择了8,在第四层的(9 ,5),必然要选择5(21>19)

                             那么路径最大只能是 8—> 5—>16= 29;

........

以此类推,直到第二层,就知道从第一层该怎么选,加上第二层的最大路径,就是题目要求的最大路径。

用表格表示:

59

50

49

38

34

29

21

28

19

21

19

7

10

4

16

代码实现解析

#include <iostream>
#include <algorithm>

using namespace std;


int data[50][50];//存储原始数据
int dp[50][50];//存储动态规划过程中的数据
int n;//塔的层数

void ShuT()
{
    //先将数塔最底层数据放入动态规划dp数组第五层
    for (int i = 0; i < n; ++i)
    {
        dp[n - 1][i] = data[n - 1][i];
    }  


    //临时存放向下向右两个值的,最大那个
    int temp_max;


    //开始往dp数组中存放每个小阶段的路径值
     
   for (int i = n - 1; i >= 0; --i)     //层数,从下往上进行
    {
        for (int j = 0; j <= i; ++j)    //不同层数值的位置
        {
            // 使用递推公式计算dp的值
            temp_max = max(dp[i + 1][j], dp[i + 1][j + 1]); //取向下,向右的最大值
            dp[i][j] = temp_max + data[i][j];              //dp数组存放当前路径的最大值
        }
    }

}


int main()
{
   
    cin>>n;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j <= i; ++j)
        {
            cin >> data[i][j];
        }
    }

    ShuT();
     cout << "最大路径和:" << dp[0][0] <<endl;
}

若有不足之处,希望大家多多提出建议,共同进步!!!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

桑稚远方~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值