基准时间限制:1 秒 空间限制:131072 KB 分值: 5
难度:1级算法题
一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值。
每次只能走到下一层相邻的数上,例如从第3层的6向下走,只能走到第4层的2或9上。
5
8 4
3 6 9
7 2 9 5
例子中的最优方案是:5 + 8 + 6 + 9 = 28
Input
第1行:N,N为数塔的高度。(2 <= N <= 500) 第2 - N + 1行:每行包括1层数塔的数字,第2行1个数,第3行2个数......第k+1行k个数。数与数之间用空格分隔(0 <= A[i] <= 10^5) 。
Output
输出最大值
Input示例
4 5 8 4 3 6 9 7 2 9 5
Output示例
28
思路:
这是一道典型的动态规划问题。
考虑从底层的结点开始计算。【假定从上往下的层数记为:1-N】
第i层走到第i+1层取决于 第i+1层结点的最大值。
具体实现时 用一个一维数组保存从底往上的结果,可以减小空间复杂度。
注:本文给出的算法时间复杂度 O(n)
贴代码:
<span style="font-size:12px;">#include <stdio.h>
#include <stdlib.h>
// 定义求两个数的最大值宏
#define Max(a,b) ((a) > (b) ? (a) : (b))
int main(void)
{
int n , m , i , k , j;
// 输入塔的层数
scanf("%d", &n);
// n层塔总共有多少个数
k = (1 + n) * n / 2;
// 记录所有数的动态数组
int *a = (int*)malloc(sizeof(int) * k);
// 输入每个塔结点的数
for(i = 0 ; i < k; i++)
{
scanf("%d", a + i);
}
// 从倒数第二层的结点开始
k = k - n;
// 若按照从上到下 从左到右的次序对结点计数
// 从倒数第二层的最后一个结点开始 决策往左还是往右
for(i = k - 1 , j = 0 ; i >= 0; i--)
{
a[i] = a[i] + Max(a[i+n], a[i+n-1]);
// 遍历完一层的结点
if(++j == n - 1)
{
n--;
j = 0;
}
}
printf("%d\n",a[0]);
return 0;
}</span>