动态规划 数字三角形

题目:有一个迷宫是一个被称为“数字三角形”的n(n不超过200)层迷宫,这个迷宫的第i层有i个房间,分别编号为1..i。除去最后一层的房间,每一个房间都会有一些通往下一层的房间的楼梯,用符号来表示的话,就是从第i层的编号为j的房间出发会有两条路,一条通向第i+1层的编号为j的房间,另一条会通向第i+1层的编号为j+1的房间,而最后一层的所有房间都只有一条离开迷宫的道路。这样的道路都是单向的,也就是说当沿着这些道路前往下一层的房间或者离开迷宫之后,没有办法再次回到这个房间。迷宫里同时只会有一个参与者,而在每个参与者进入这个迷宫的时候,每个房间里都会生成一定数量的奖券,这些奖券可以在通过迷宫之后兑换各种奖品。参赛者小Ho的起点是在第1层的编号为1的房间,现在小Ho悄悄向其他参与者弄清楚了每个房间里的奖券数量,希望小Hi帮他计算出他最多能获得多少奖券。

迷宫示意图

如图 蓝色箭头所指即为迷宫的最佳路线

方法一:暴力 ×(时间消耗为2的n次方倍)
方法二:DFS √

DFS还要进行一次优化:
由图可知当走到第三排的时候,实际上可以明确对于上一次的2条线路的最大值。
为了进行这样的优化,我们需要记录一个值best(i, j)——当前搜索过的路径中到达第i层第j个房间时最多能获取多少奖券,然后在每次进入一个房间的时候,都检查当前的sum与best(i, j)的大小关系,如果sum小于等于best(i, j)的话,就没有必要继续搜索了呢。比如在之前的例子中,当通过绿色路径到达第3层第2个房间的时候,best(i, j)=10,而sum = 8,所以是没有必要继续往下搜索的。”

总结公式

然后就可以得出一个公式。所以可以直接用来写了。

#include<cstdio>
#include<algorithm>
using namespace std;
int reward[105][105];
int best[105][105];
int main()
{
    int n, i, j, sum=0, maxx=-1;
    scanf("%d", &n);
    for(i=0; i<n; i++)
    {
        for(j=0; j<=i; j++)
        {
            scanf("%d", &reward[i][j]);
        }
    }
    for(i=0; i<n; i++)
    {
        for(j=0; j<=i; j++)
        {
            if(!i && !j) best[i][j]=reward[i][j];
            else if(!j) best[i][j]=best[i-1][j]+reward[i][j];
            else if(i==j) best[i][j]=best[i-1][j-1]+reward[i][j];
            else best[i][j]=max(best[i-1][j-1],best[i-1][j])+reward[i][j];
        }
    }
    for(i=0; i<n; i++)
    {
        if(best[n-1][i]>maxx) maxx=best[n-1][i];
    }
    printf("%d\n", maxx);
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 题目重述描述73 88 1 02 7 4 44 5 2 6 5(图1) 图...
    一颗白菜_阅读 10,803评论 0 3
  • 问题描述 在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左...
    icecrea阅读 3,991评论 0 0
  • 题目要求 在上面的数字三角形中寻找一条从顶部到底边的路径(注意是底边),使得路径上经过的数字之和最大.路径上的每一...
    Co_zy阅读 3,196评论 0 0
  • 题目描述给出一个数字三角形。 请编一个程序计算从顶至底的某处的一条路径,使该路径所经过的数字的总和最大。规定:(1...
    放下梧菲阅读 4,266评论 0 0
  • 给定一个由n行数字组成的数字三角形,设计一个算法,计算出从三角形的顶至底的一条路径,使该路径经过的数字总和最大。输...
    Super_邓帅阅读 5,921评论 0 0