2760:数字三角形
描述
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
(图1)
图1给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
注意:路径上的每一步只能从一个数走到下一层上和它最近的左边的那个数或者右边的那个数。
输入
输入的是一行是一个整数N (1 < N <= 100),给出三角形的行数。下面的N行给出数字三角形。数字三角形上的数的范围都在0和100之间。
输出
输出最大的和。
样例输入
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
样例输出
30
来源
翻译自 IOI 1994 的试题
问题链接:Bailian2760 数字三角形
问题描述:(略)
问题分析:
动态规划问题,有2种解法。
解法一:使用额外数组,从底向上计算。需要注意数组大小!要多一行和一列保证可靠。
解法二:不使用额外数组,自顶向下计算。
这个题与参考链接是同一个题,只是输入数据格式略有不同。
程序说明:(略)
参考链接:HDU2084 数塔【DP】
题记:(略)
AC的C语言程序(解法一)如下:
/* Bailian2760 数字三角形 */
#include <stdio.h>
#include <string.h>
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 100
int a[N + 1][N + 1], dp[N + 1][N + 1];
int main(void)
{
int n, i, j;
scanf("%d", &n);
for(i = 0; i < n; i++)
for(j = 0; j <= i; j++)
scanf("%d", &a[i][j]);
memset(dp, 0, sizeof(dp));
for(i = n - 1; i >= 0; i--)
for(j = 0; j <= i; j++)
dp[i][j] = MAX(dp[i+1][j], dp[i+1][j+1]) + a[i][j];
printf("%d\n", dp[0][0]);
return 0;
}
AC的C语言程序(解法二)如下:
/* Bailian2760 数字三角形 */
#include <stdio.h>
#include <string.h>
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 100
int grid[N][N];
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] = MAX(grid[i][j] + grid[i-1][j-1], grid[i][j] + grid[i-1][j]);
int maxv = 0;
for(i=n-1, j=0; j<n; j++)
if(grid[i][j] > maxv)
maxv = grid[i][j];
return maxv;
}
int main()
{
int n, i, j;
scanf("%d", &n);
memset(grid, 0, sizeof(grid));
for(i = 0; i < n; i++) {
for(j = 0; j <= i; j++)
scanf("%d", &grid[i][j]);
}
printf("%d\n", setmax(n));
return 0;
}