1208: 数字三角形
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 15 Solved: 10
[ Submit][ Status][ Web Board]
Description
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
在上面的数字三角形中寻找一条从顶部到底边的路径,使得 路径上所经过的数字之和最大。路径上的每一步都只能往左下或 右下走。只需要求出这个最大和即可,不必给出具体路径。
三角形的行数大于1小于等于100,数字为 0 - 99
Input
输出包含多组样例文件尾结束。
第一行是三角形的行数1<N<=100。
接着N行输入数字三角形。
Output
输出数字最大和。
Sample Input
5
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11
Sample Output
86
动态规划的入门题目,可以从底部往上推
dp[i][j] 表示走到第i行第i列的最大和
数塔问题描述:
如下图所示的数塔,从顶部出发到底层,试着找出一条路径使该路径所走过的数值和最大。
上图中问题解路径就是
使用动态规划求解:
1、 阶段划分
从数塔特点看,应该自下而上逐层决策。
第五层的八个数,做如下的4次决策。
对经过第四层2的路径,第五层的19,7中选择了19
对经过第四层18的路径,第五层的10,7中选择了10
对经过第四层9的路径,第五层的10,4中选择了10
对经过第四层5的路径,第五层的4,16中选择了16
这可以看作是一次决策的过程,一次递推和降阶过程,因为它使5层的问题变为4层的子问题。
递推出第4层与第5层的和为:
21(2+19), 28(18,10), 19(9+10), 21(5+16),
用同样的方法依次类推,将4层问题变成3层,继而变为1阶,就能得到最优解了。
2、 存储,求解
原始信息存储:层数n和每一层的数据存在data二维数组中。
二维数组d存储内容如下:
d[n][j]=data[n][j] j=1,2,…n
d[i][j]=max(d[i+1][j],d[i+1][j+1])+data[i][j]
最后d[1][1]就是最优路径的值。
3、 最优解路径的求解
data数组存储内容 数组d存储的内容
9 59
12 15 50 49
10 6 8 38 34 29
2 18 9 5 21 28 19 21
19 7 10 4 16 19 7 10 4 16
路径的输出:data与d数组对照看
输出d[1][1] 中的9
b=d[1][1] – datap[1][1]=59-9=50
b与d[2][1],d[2][2]比较,b与d[2][1]相等(50),则输出data[2][1]=12
……依次类推就能得到完整路径
。
9+12+10+18+10=59#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int a[2000][2000];
int main()
{
int t,n,i,j;
while(~scanf("%d",&n))
{
for(i=0; i<n; i++)
for(j=0; j<=i; j++)
scanf("%d",&a[i][j]);
for(i=n-1; i>0; i--)
for(j=0; j<i; j++)
a[i-1][j]+=max(a[i][j],a[i][j+1]);
printf("%d\n",a[0][0]);
}
return 0;
}