[动态规划]数字三角形

动态规划一直是一个很头疼的问题啊。

最近在看这方面的东西,记录一下刘汝佳书里的动态规划章节里的数字三角形题目。

这道题很基础,但总结的三个动态规划很清晰。

有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数,形如:
               1
            3    2
          4   10   1
        4   3    2   20
每个结点都可到它左右子结点,例如3可以到4也可以到10.
从第一行开始每次可以往左下或右下走一格,直到走到最下,把沿途结点的值相加,如何走才能得到最大值。

如果遍历的话,n层会有2的n次方种可能性,显然规模太大。所以换一种思路。
其实最难的是跨出第一步,也就是在结点1,是要向左走还是向右走。因此对于1来讲,如果它能够知道向左跟向右现在的值是多少,它就可以迈出第一步。

我们用i,j表示第i层第j个结点

因此就有 d(i,j)=value(i,j)+max{d(i+1,j),d(i+1,j+1)}

这就是这道题的状态转移方程。

算法1:递归

int d (int i,int j){
    return a[i][j] + (i==n?0 : d(i+1,j)>?d(i+1,j+1));
}

嗯。。思路很直接。。语法很简练。。就是耗时会很长,而且层数一多可能就栈溢出了。

算法2:递推

int i,j;
for(j=1;j<=n;j++) d[n][j]=a[n][j];
for(i=n-1;i>=1;i++)
    for(j=1;j<=i;j++)
        d[i][j]=a[i][j]+d[i+1][j]>?d[i+1][j+1];

用二维数组d[i][j]保存状态,用递推的方法从i=1开始,因此当计算d(i,j)需要d(i-1,j) 和d(i-1,j+1)时这两个状态已经计算好了。

算法3:记忆化搜索

int d(int i,int j){
    if(d[i][j]>=0) return d[i][j];
    return a[i][j]=a[i][j]+(i==n?0:d(i+1,j)>?d(i+1,j+1);

这是对算法1的改进,算法1没有对状态进行保存,这里借用d[i][j]来保存状态,并且用 -1 来表示d[i][j]状态还没有被计算过,因此当>=0时就可以直接返回。

时间: 2024-08-10 23:18:57

[动态规划]数字三角形的相关文章

动态规划--数字三角形问题

1. 问题描述 有一个像这样的数字三角形: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 从顶点开始,每个数字向下层走只能有左下和右下两个方向,求出到达最后一行时最大的路径之和. Input 第1 行是数字三角形的行数n,1<= n <=100. 接下来n行是数字三角形各行中的数字.所有数字在0---99之间. 比如Input是: 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 则output是30. 2. 问题求解 这是一个典型的动态规划求解问题,因为它符合动态

动态规划 数字三角形(递归,递推,记忆化搜索)

题目要求: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 在上面的数字三角形中寻找在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大.路径上的每一步都只能往左下或右下走.只需要求出这个最大和即可,不必给出具体路径. 三角形的行数大于1小于等于100,数字为 0 - 99 输入格式: 5 //三角形行数.下面是三角形 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 解题思路: 用二维数组存放数字三角形 D[r][j] //表示第i行第j个元素的

七:动态规划-数字三角形

问题: 数字三角形  问题描述 (图3.1-1)示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和最大. ●每一步可沿左斜线向下或右斜线向下走: ●1<三角形行数≤100: ●三角形中的数字为整数0,1,-99: (图3.1-1)输入格式 文件中首先读到的是三角形的行数. 接下来描述整个三角形输出格式 最大总和(整数)样例输入573 88 1 02 7 4 44 5 2 6 5样例输出 30 方法一: 1 #include<stdio.h> 2

动态规划&mdash;&mdash;数字三角形(递归or递推or记忆化搜索)

动态规划的核心就是状态和状态转移方程. 对于该题,需要用抽象的方法思考,把当前的位置(i,j)看成一个状态,然后定义状态的指标函数d(i,j)为从格子出发时能得到的最大和(包括格子本身的值). 在这个状态定义下,原问题的解就是d(i,j). 下面看一下不同状态之间如何转移.从格子(i,j)出发有两种策略.如果向左走,则到(i+1,j)后需要求"从(i+1,j)出发能得到的最大和"这一问题,即d(i+1,j). 类似的,往右走之后需要求解d(i+1,j+1).由于可以在这两个决策中自由选

动态规划入门-数字三角形(从朴素递归到各种优化)

数字三角形(POJ1163) Description 73 88 1 02 7 4 44 5 2 6 5 在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大.路径上的每一步都只能往左下或右下走.只需要求出这个最大和即可,不必给出具体路径.三角形的行数大于1小于等于100,数字为 0 - 99 输入格式:5 //三角形行数.下面是三角形73 88 1 02 7 4 4 4 5 2 6 5 要求输出最大和 Sample Output 30 Source IOI 1994

数字三角形,从递归到动态规划

 一.实践题目 数字三角形 给定一个由 n行数字组成的数字三角形如下图所示.试设计一个算法,计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大. 输入格式: 输入有n+1行: 第 1 行是数字三角形的行数 n,1<=n<=100. 接下来 n行是数字三角形各行中的数字.所有数字在0..99 之间. 输出格式: 输出最大路径的值. 输入样例: 在这里给出一组输入.例如: 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 输出样例: 在

简单动态规划---动态的数字三角形

动态的数字三角形 难度级别:B: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 一个数字组成的三角形,有n行,第i行有i个数.从第一个数开始,每次可以往左下或右下走一格,直到走到最后一行,把沿途经过的数全部加起来.如何走才能得到最大的和?    举个例子:                           为了简单起见,输入时将每行的数依次输入,第一个数之前并不输入空格. 输入 第一行:n,表示这个三角形共有n行第二至n+1行:依次为这

数字三角形(蓝桥杯 动态规划)

问题描述 (图3.1-1)示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和最大. ●每一步可沿左斜线向下或右斜线向下走: ●1<三角形行数≤100: ●三角形中的数字为整数0,1,-99: . (图3.1-1) 输入格式 文件中首先读到的是三角形的行数. 接下来描述整个三角形 输出格式 最大总和(整数) 样例输入 573 88 1 02 7 4 44 5 2 6 5 样例输出 30 从最下面往上找,由局部最优解找整体最优解. #include<st

hiho#1037 : 数字三角形 (动态规划)

#1037 : 数字三角形 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 问题描述 小Hi和小Ho在经历了螃蟹先生的任务之后被奖励了一次出国旅游的机会,于是他们来到了大洋彼岸的美国.美国人民的生活非常有意思,经常会有形形色色.奇奇怪怪的活动举办,这不,小Hi和小Ho刚刚下飞机,就赶上了当地的迷宫节活动.迷宫节里展览出来的迷宫都特别的有意思,但是小Ho却相中了一个其实并不怎么像迷宫的迷宫--因为这个迷宫的奖励非常丰富~ 于是小Ho找到了小Hi,让小Hi帮助他获取尽可能多的