径,使该路径所经过的数字的总和最大。
●每一步可沿左斜线向下或右斜线向下走;
●1<三角形行数≤100;
●三角形中的数字为整数0,1,…99;

(图3.1-1)
接下来描述整个三角形
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
分析:
我的第一反应是利用深度优先遍历穷举出所有路径的值并进行比较
开始确实行之有效,但是随着行数的增加,不可避免地运行超时了
试着化简,还是无效。
后来查找答案,才知道还有一种叫做动态规划的方法,
即把问题拆成许多步,求出每一步的最优解,直到求该问题的最优解
每个步的最优解是从它前面步骤最优解里面选出的
比如这个问题,求第1层到第n层的数字总和最大
我们可以拆成如下若干问题:
1、第n层到第n-1层最大值;
2、在1的基础上,第n-1层到第n-2层最大值;
3、在2的基础上,第n-2层到第n-3层最大值
...
n、在前面问题的基础上,求第2层到第一层的最大值
由于题目对三角形路径有限定
即第n层的第i号只能走到第n+1层的第i,i+1号上(i+1<n+1)
所以每一步若干个最优解,进行下一步时,从这些最优解里面选出,求得下一步若干个最优解
说了这么多,以题目例子来试一试:
三角形:
第1层 7第2层 3 8
第3层 8 1 0
第4层 2 7 4 4
第5层 4 5 2 6 5
我们可以分成4步
(1)第5层返回第4层:怎么样相加才能最大呢?
当然是i与他左右孩子里面最大的一个相加啊!
比如第4层的2,左孩子为第5层的4,右孩子为第5层的5,肯定与有孩子相加啊
结果为2+5=7;
同理,7与右孩子(5)相加=12,4与右孩子(6)相加=10,4与左孩子(6)相加=10
加完一遍后,第4层从2 7 4 4 变成了 7 12 10 10
本步骤的最优解即7 12 10 10
(2)第4层返回第3层:因为(1),得:
第3层: 8 1 0
第4层:7 12 10 10
同理(1),第二层的最优解为:20 13 10
(3)第3层返回第2层
第2层 3 8
第3层 20 13 10
最优解:23 21
(4)第2层返回第1层(最终问题)
第1层 7
第2层 23 21
最优解(最终答案):30
经过这么一分析,我也得到了动态转移方程:
a[i-1][j] = a[i][j] + max( a[i][j] , a[i][j+1] );(j+1<i)
#include <stdio.h>
int a[105][105];
int num;
void dp(int n){
for(int i=n-1;i>0;--i){
for(int j=0;j<n-1;++j){
if(a[i][j]>a[i][j+1]){
a[i-1][j]=a[i][j]+a[i-1][j];
}else{
a[i-1][j]=a[i][j+1]+a[i-1][j];
}
}
}
}//动态规划
int main(){
int k;
scanf("%d",&num);
int i,j;
for(i=0;i<num;++i){
for(j=0;j<i+1;++j){
scanf("%d",&a[i][j]);
}
}
dp(num);
printf("%d",a[0][0]);
return 0;
}