1.题目信息(http://poj.org/problem?id=1163)
The Triangle
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 30397 | Accepted: 17973 |
Description
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1)
Input
Your program is to read from standard input. The first line contains one integer N: the number of rows in the triangle. The following N lines describe the data of the triangle. The number of rows in the triangle is > 1 but <= 100. The numbers in the triangle, all integers, are between 0 and 99.
Output
Your program is to write to standard output. The highest sum is written as an integer.
Sample Input
5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
Sample Output
30
2.算法分析
本题是经典的动态规划题,要求出要求的最大值(最优)。大致意思是,从三角形顶部数字走,每次只能走到这个数字的左下角或者右下角的数字,直到底部,计算走过的线路的数字之和,求这个和的最大值,我们暂且称之为数字的最大路线和。我们可以转换为求任意数字的最大路线和,本题要求的最大值即:所有数字的最大路线和的最大值。比如,我们要求数字1的最大路线和,则最大路线是: 7->8->1,最大路线和就是16 。我们把三角记录在数组a中,把数字的最大路线和数组m中,则动态规划方程如下:
m[ i ][ j ] = max { m[ i -1][ j-1 ] + m[ i-1][ j ] } + a[ i ][ j ]
即:某一数字的最大路线和 = max {左上角数字最大路线和,右上角数字最大路线和} + 该数字值
3.参考代码
/*
Name: POJ1163 The Triangle
Author:chenbin
Date: 09-10-12 12:00
Description: http://poj.org/problem?id=1163
*/
#include <stdio.h>
#include <string.h>
int main()
{
short int a[100][100],i = 0,j = 0,N,max = 0,upleft = 0,upright = 0;
memset(a,0,sizeof(a));
scanf("%d",&N);
for(i = 0;i < N ; i++)
{
for(j = 0 ; j <= i ; j++)
{
scanf("%d",&a[i][j]);
short upleft = (i-1 >= 0)&&(j-1 >= 0) ? a[i-1][j-1] : 0;
short upright = (i-1 >= 0) ? a[i-1][j] : 0;
a[i][j] = ( upleft > upright ? upleft : upright )+ a[i][j];
max = a[i][j] > max ? a[i][j] : max;
}
}
printf("%d",max);
return 0;
}
4.代码优化
可从如下几个方面优化代码
(1).数组采用压缩矩阵,可以节省一半内存
(2).将i=0,j=0的特殊情况特殊处理,可消除upleft和upright的的判断,甚至可以不用这两个变量。
(3).定义宏,替换?:求最大值的方式。
如有其它好的算法和代码,欢迎讨论