DP入门(1)——数字三角形问题

一、问题描述

  如上图所示,有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数。现请你在此数字三角形中寻找一条从首行到最下行的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或右下走。只需要求出这个最大和即可,不必给出具体路径。 三角形的行数大于1小于等于100,数字为 0 - 99 。

二、问题分析

  要求找出一条路径,它经过的数字之和最大。我们可以细化到每一步,每一次往下走都要选择较大的数。

  于是可以得出下面的以下的伪代码:

if(当前行是最下行)
	当前行到最下行的最大和 = 当前数字的值
else
	当前行到最下行的最大和 = 下一行到最下行的最大和 + 当前数字的值

  这样的伪代码实在是难读,因此我们需要用抽象的方法思考问题(即变量化):

  • (i , j):当前的位置(状态)
  • a(i , j):表示第 i 行的第 j 个数字          //i , j > 0
  • d(i , j):从位置(i , j)到最下行的最大和    //状态(i , j)的指标函数,且原问题的解是d(1,1)

  于是,上面的伪代码转化为:

if(i == n)
	d(i,j) = a(i,j);
else
	d(i,j) = max{d(i+1,j),d(i+1,j+1)} + a(i,j);

  我们来看不同的状态之间是怎么转移的:从位置(i , j)出发有两种决策,①往左走,则走到(i+1 , j)后,将要求解d(i+1 , j);②往右走,则走到(i+1 , j+1)后,将要求解d(i+1 , j+1)。

  由于可以在这两个决策中自由选择,所以应选择d(i+1 , j)和d(i+1 , j+1)中较大的那个。这一步正导出了所谓的状态转移方程:

  • d(i , j)= max{d(i+1 , j), d(i+1 , j+1)} + a(i , j)

  这个方程已经蕴含了最优质结构性质(全局最优解包含局部最优解)。即如果连“从(i+1 , j)或(i+1 , j+1)出发到最下行”这部分的和都不是最大的,加上a(i , j)之后肯定也不是最大的。

三、解题方式

1. 递归计算

int solve(int i,int j)
{
	if(i == n)	return a[i][j];
	else	return max(solve(i+1,j),solve(i+1,j+1)) + a[i][j];
}

  分析:用直接递归的方法计算状态转移方程,效率往往十分低下。其原因是相同的子问题被重复计算。

2. 递推计算

for(int j=1;j<=n;j++)	d[n][j] = a[n][j];		//最后一行
for(int i=n-1;i>=1;i--)
	for(int j=1;j<=i;j++)
		d[i][j] = max(d[i+1][j],d[i+1][j+1]) + a[i][j];

  分析:i 是逆序枚举的,所以在计算d[i][j]前,它所需要的d[i+1][j]和d[i+1][j+1]都已经计算出来了。

  提示:可以用递推法计算状态转移方程,递推的关键是边界和计算顺序。

3. 记忆化搜索

/*	第一部分:将d全部初始化为-1	*/
memset(d,-1,sizeof(d));
/*	第二部分:编写递归函数	*/
int solve(int i,int j)
{
	if(d[i][j] != -1)	return d[i][j];	    //判断状态(i,j)是否已经被计算过
	if(i == n)	return d[i][j] = a[i][j];
	else	return d[i][j] = max(solve(i+1,j),solve(i+1,j+1)) + a[i][j];
}

  分析:此程序是递归的,但是它同时把计算结果保存在数组d中。所以,千万别忘记在计算之后把它保存在d[i][j]中。此程序的方法称为记忆化,它虽然不像递推法那样显式地指明了计算顺序,但仍然可以保证每个结点只访问一次。

  提示:根据C语言“赋值语句本身有返回值”的规定,可以把保存d[i][j]的工作合并到函数的返回语句中。

  提示:可以用记忆化搜索的方法计算状态转移方程。当采用记忆化搜索时,不必事先确定各状态的计算顺序,但需要记录每个状态“是否已经计算过”。

时间: 2024-10-24 08:23:24

DP入门(1)——数字三角形问题的相关文章

【基础练习】【棋盘DP】codevs2193 数字三角形ww题解

转载请注明出处 CSDN ametake版权所有 题目描述 Description 数字三角形必须经过某一个点,使之走的路程和最大 输入描述 Input Description 第1行n,表示n行 第2到n+1行为每个的权值 程序必须经过n div 2,n div 2这个点 输出描述 Output Description 最大值 样例输入 Sample Input 2 1 1 1 样例输出 Sample Output 2 数据范围及提示 Data Size & Hint n <=25 今天听

DP 例题: 数字三角形

从上层到最底层进行走迷宫,路过房间拿到奖劵,问累积最多拿多少奖劵 Code: 1 #include <stdio.h> 2 #include <iostream> 3 #include <algorithm> 4 #include <math.h> 5 #include <string.h> 6 #include <vector> 7 #include <queue> 8 using namespace std; 9 10

4829 [DP]数字三角形升级版

4829 [DP]数字三角形升级版 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 从数字三角形的顶部(如图,第一行的5表示行数)到底部有很多条不同的路径.对于每条路径,把路径上面的数加起来可以得到一个和,且!!!!!!!!! ================================================================================== =================

数字三角形 17 初入dp

Description 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 给出了一个数字三角形.从三角形的顶部到底部有很多条不同的路径.对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和. 注意:路径上的每一步只能从一个数走到下一层上和它最近的左边的那个数或者右边的那个数. Input 输入数据有多组,每组输入的是一行是一个整数N (1 < N <= 100),给出三角形的行数.下面的N行给出数字三角形.数字三角形上的数的范围都在0和100之间. Output

LightOJ 1004 Monkey Banana Problem (DP 数字三角形)

1004 - Monkey Banana Problem PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB You are in the world of mathematics to solve the great "MonkeyBanana Problem". It states that, a monkey enters into a diamond shaped twodimen

xbz分组题B 吉利数字 数位dp入门

B吉利数字时限:1s [题目描述]算卦大湿biboyouyun最近得出一个神奇的结论,如果一个数字,它的各个数位相加能够被10整除,则称它为吉利数.现在叫你计算某个区间内有多少个吉利数字. [输入]第一行为样例个数N.接下来N行,每一行代表一个输入样例,每个输入样例有2个数,分别代表某个区间的起点a和终点b.注意所求区间为[a,b],1<=a<=b<=10^9 [输出]N行.对于第x个输入样例,在第x行输入该样例所对应的结果. [输入样例]21 101 20 [输出样例]01 [Hint

hihoCoder#1037 : 数字三角形(DP)

[题目链接]:click here~~ 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 问题描写叙述 小Hi和小Ho在经历了螃蟹先生的任务之后被奖励了一次出国旅游的机会,于是他们来到了大洋彼岸的美国.美国人民的生活很有意思,常常会有形形色色.奇奇怪怪的活动举办.这不,小Hi和小Ho刚刚下飞机,就赶上了当地的迷宫节活动. 迷宫节里展览出来的迷宫都特别的有意思.可是小Ho却相中了一个事实上并不怎么像迷宫的迷宫--由于这个迷宫的奖励很丰富~ 于是小Ho找到了小Hi,让小Hi帮助

算法训练 数字三角形(DP)

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

HDU 1176(类似数字三角形的题,很经典,值得仔细理解的dp思维)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1176 免费馅饼 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 60927    Accepted Submission(s): 21380 Problem Description 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径