CCF NOI1145 数字金字塔【DP】
问题链接:CCF NOI1145 数字金字塔。
时间限制:
1000 ms 空间限制: 262144 KB
题目描述
观察下面的数字金字塔。写一个程序查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以从当前点走到左下方的点也可以到达右下方的点。
在上面的样例中,从7到3到8到7到5的路径产生了最大的和30。
输入
第一个行包含R(1<= R<=1000),表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
所有的被供应的整数是非负的且不大于100。
输出
单独的一行,包含那个可能得到的最大的和。
样例输入
57
3 8
8 1 0
2 7 4 4
4 5 2 6 5
样例输出
30
数据范围限制
1<= R<=1000
提示
问题分析
这个题与《Project Euler Problem 18 Maximum path sum I》几乎相同。其中,最大行数不一样,需要改为1000,此外输入就一个三角形(原题需要重复计算多个三角形)。
直接计算就可以了,关键是如何用二维数组存储数据,以及数据之间的规律(递推计算过程)。
程序说明
程序是CV过来的,小改一下就AC了。
要点详解- 程序写多了,似曾相识的也就多了。
Project Euler Problem 18 Maximum path sum I
100分通过的C语言程序:
#include <stdio.h> #include <string.h> #define N 1000 int grid[N][N]; int max; int mymax(int left, int right) { return left > right ? left : right; } int setmax(int n) { int i, j; for(i=1; i<n; i++) for(j=0; j<=i; j++) if(j == 0) grid[i][j] += grid[i-1][j]; else grid[i][j] = mymax(grid[i][j] + grid[i-1][j-1], grid[i][j] + grid[i-1][j]); int max = 0; for(i=n-1, j=0; j<n; j++) if(grid[i][j] > max) max = grid[i][j]; return max; } int main(void) { int r, i, j; memset(grid, 0, sizeof(grid)); scanf("%d", &r); for(i=0; i<r; i++) for(j=0; j<=i; j++) scanf("%d", &grid[i][j]); int max = setmax(r); printf("%d\n", max); return 0; }