动态规划之五:数字三角形

原创 2018年04月17日 16:39:05

问题:将一个由n行数字组成的三角形,如图所示,设计一个算法,计算出三角形的由顶至底的一条路径,使该路径经过的数字总和最大?


图1数字三角形


       首先拿到这题,我们第一想法肯定是使用深度优先算法DFS或者广度优先算法BFS,但是使用DFS算法需要遍历所有点,搜索时会重复遍历一些点,导致时间成指数增长。


图2重复计算的次数

设我们用二维数组map[m][n]来存储数字三角形,把图1转换成实际的存储格式:


图3数字三角形存储格式

如图2和图3所示,我们通过观察可以发现,三角形的边界位置如3、8、2 、4等的位置只需要计算一次,而中间的位置数字例如1的计算次数为上一行3的次数加上8的次数,则次数计算公式为:

                                            map[i][j]=map[i-1][j-1]+map[i-1][j]  ( i>0&&i<=m,j>0&&j<=n     )


      map[i][j]来表示第i行第j个数字( i和j都是从1开始),现在来使用DFS分析可以发现,从map[i][j]出发,我们可以选择的下一条路径只有map[i+1][j]或者map[i+1][j+1],因此递推公式可以描述为

                                  max(i,j)=max ( max(i+1,j) , max(i+1,i+1) ) +map[i][j]

  

                                                                                  图4递归遍历方式

程序结果:

#include <iostream>    
 
#define MAX 10    
using namespace std;
int map[MAX][MAX];
int n;
int Max(int i, int j) {
	if (i == n)
		return map[i][j];
	int x = Max(i + 1, j);
	int y = Max(i + 1, j + 1);
	return (x>y?x:y) + map[i][j];
}
int main() {
	int i, j;
	cin >> n;
	for (i = 1; i <= n; i++)
		for (j = 1; j <= i; j++)
			cin >> map[i][j];
	cout << Max(1, 1) << endl;
	system("pause");
}

虽然使用递归可以解决问题,但是效率不高,想要提高效率就需要数字三角形中的每个数字只需要计算一遍即可,我们使用f[i][j]来保存表示从顶点(1, 1)到顶点(i, j)的最大值。

通过对上面的递归地分析可得状态转移函数为:

            f[i][j]=max(f[i+1][j],f[i+1][j+1])+map[i][j]

程序结果如下:

#include<iostream>

#define size 20
using namespace std;

int main() {
	int map[size][size];
	int  n;
	cin  >> n;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= i; j++)
			cin >> map[i][j];
		
	for (int i = n - 1; i > 0; i--)
		for (int j = 1; j <= i; j++)
			map[i][j] += (map[i + 1][j] > map[i + 1][j + 1] ? map[i + 1][j] : map[i + 1][j + 1]) ;

	cout << map[1][1] << endl;
	system("pause");
	return 0;
}




算法 -- 数字三角形之动态规划

好久没有好好写算法啦,因此今天晚上就思考实现老师说的一道算法题目: 用动态规划求解数字三角形. 下面简单描述下题目含义: 数字三角形中的数字要求为不超过100的非负整数.题目规定从最顶层开始往下走...
  • u013166575
  • u013166575
  • 2015-11-20 01:10:22
  • 2117

经典动态规划问题--数字三角形 POJ--1163

经典动态规划问题--数字三角形 POJ--1163
  • linsheng9731
  • linsheng9731
  • 2014-04-16 13:38:11
  • 1541

数字三角形问题 (动态规划初步)

问题描述: 有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数。    从第一行的数开始,每次可以往左下或右下走一格,直到走到最下行,把沿途经过的数全部...
  • eagle_or_snail
  • eagle_or_snail
  • 2016-03-30 21:17:19
  • 2849

动态规划(DP)之入门学习-数字三角形

数字三角形案例题目描述 Description下图给出了一个数字三角形,请编写一个程序,计算从顶至底的某处的一条路径,使该路径所经过的数字的总和最大。 (1)每一步可沿左斜线向下或右斜线向下 ...
  • zwhlxl
  • zwhlxl
  • 2015-05-29 10:11:34
  • 9549

蓝桥杯-动态规划-java算法训练 数字三角形

问题描述   (图3.1-1)示出了一个数字三角形。 请编一个程序计算从顶至底的某处的一条路   径,使该路径所经过的数字的总和最大。   ●每一步可沿左斜线向下或右斜线向下走;   ●1<三角形行数...
  • qq_34594236
  • qq_34594236
  • 2016-04-16 09:51:41
  • 3060

【动态规划】数字三角形问题

Description 给定一个由n行数字组成的数字三角形如下图所示。试设计一个算法,对于给定的由 n行数字组成的数字三角形, 计算从三角形的顶至底的路径经过的数字和的最大值。 注意:...
  • u010932314
  • u010932314
  • 2014-07-08 17:36:58
  • 1244

算法:动态规划-数字三角形的最优解(打印路径)

算法:动态规划-数字三角形的最优解(打印路径)
  • bensonrachel
  • bensonrachel
  • 2017-11-28 21:02:47
  • 278

【动态规划】数字三角形最大值(一)(递归)

避免 递归函数 的重复计算!
  • FarCaptain
  • FarCaptain
  • 2017-04-15 22:15:36
  • 642

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

数字三角形问题 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 给定一个由n行数字组...
  • do_you_ac_today
  • do_you_ac_today
  • 2017-02-16 09:06:38
  • 191

动态规划(入门):各种数字三角形

一、一般的数字三角形:         给一个由数字形成的三角形,要求从三角形的顶端开始走,走到最后一行,要求走的路径之和最大。对于一般的数字三角行,可以正着走,也可以反着走。建议最好正走,不然加强版...
  • yopilipala
  • yopilipala
  • 2017-06-01 16:15:51
  • 392
收藏助手
不良信息举报
您举报文章:动态规划之五:数字三角形
举报原因:
原因补充:

(最多只允许输入30个字)