The Triangle | ||||||
| ||||||
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. For each test case, 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. Process to the end of file. | ||||||
Output | ||||||
For each test case, your program is to write to standard output. The highest sum is written as an integer. | ||||||
Sample Input | ||||||
5 | ||||||
Sample Output | ||||||
30 |
从顶点出发时到底向左走还是向右走应取决于是从左走能取到最大值还是从右走能取到最大值,只要左右两道路径上的最大值求出来了才能作出决策。
同样,下一层的走向又要取决于再下一层上的最大值是否已经求出才能决策。这样一层一层推下去,直到倒数第二层时就非常明了。
如数字2,只要选择它下面较大值的结点19前进就可以了。所以实际求解时,可从底层开始,层层递进,最后得到最大值。
结论:自顶向下的分析,自底向上的计算。
编写一个程序计算从顶至底的某处的一条路径,使该路径所经过的数字的总和最大。每一步可沿直线向下或右斜线向下走。
(由上至下编号)
1、最优子结构:从下往上看,最底层到底 n-1 层的最优解包含最底层到底 n 层的最优解。
2、重叠子问题:要求得从最底层到 n 层的解需求的从最低层到 n-1 层的解
3、由以上两个性质,本题最适合用动态规划解
4、状态转移方程:
res[i-1][j] = max{(array[i-1][j] + res[i][j]),(array[i-1][j] + res[i][j+1]}
说明:res:结果数组。表示第i层第j个数字到最低端的最优解。
程序代码如下:
#include<stdio.h>
#include<string>
#include<algorithm>
#include<cstring>
using namespace std;
int res[100][100];
int array[100][100];
int digui_tirangle(int array[100][100],int m)
{
int i,j;
for(j=0;j<m;j++)
{
res[m-1][j]=array[m-1][j];
}
for(i=m-1;i>=0;i--)
for(j=0;j<i;j++)
{
res[i-1][j]=max((res[i][j]+array[i-1][j]),(res[i][j+1]+array[i-1][j]));
}
return res[0][0];
}
int main()
{
int n,k,l;
memset(res,0,sizeof(res));
while(scanf("%d",&n)!=EOF)
{
for(k=0;k<n;k++)
{
for(l=0;l<=k;l++)
scanf("%d",&array[k][l]);
}
/* for(k=0;k<n;k++)
{
for(l=0;l<=k;l++)
printf("%d",array[k][l]);
}*/
int result;
result=digui_tirangle(array,n);
printf("%d\n",result);
}
return 0;
}