数塔
Time Limit : 1000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 85 Accepted Submission(s) : 47
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?

已经告诉你了,这是个DP的题目,你能AC吗?
Input
Output
Sample Input
1 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
Sample Output
30
这是一道很经典的动态规划的问题!!
这道题如果用枚举法(暴力思想),在数塔层数稍大的情况下(如31),则需要列举出的路径条数将是一个非常庞大的数目(2^30= 1024^3 > 10^9=10亿)。
考虑下:
从顶点出发时到底向左走还是向右走应取决于是从左走能取到最大值还是从右走能取到最大值,只要左右两道路径上的最大值求出来了才能作出决策。同样,下一层的走向又要取决于再下一层上的最大值是否已经求出才能决策。这样一层一层推下去,直到倒数第二层时就非常明了。如数字2,只要选择它下面较大值的结点19前进就可以了。所以实际求解时,可从底层开始,层层递进,最后得到最大值。
结论:自顶向下的分析,自底向上的计算。
AC code:#include <stdio.h>
#define N 110
int a[N][N];
int max(int a,int b)
{
return (a>b)?a:b;
}
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
int i,j;
scanf("%d",&n);
for(i = 0; i < n; i++)
for(j = 0; j <= i; j++)
scanf("%d",&a[i][j]);
for(i = n-2; i >= 0; i--)
{
for(j = 0; j <= i; j++)
a[i][j]=a[i][j]+max(a[i+1][j],a[i+1][j+1]);
}
printf("%d\n",a[0][0]);
}
return 0;
}