H - The Triangle
Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u
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
Hint
OUTPUT DETAILS:
There are three ponds: one in the upper left, one in the lower left,and one along the right side.
There are three ponds: one in the upper left, one in the lower left,and one along the right side.
对于一个有数字组成的二叉树,求由叶子到根的一条路径,使数字和最大,如:
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
这个是经典的动态规划,也是最最基础、最最简单的动态规划,典型的多段图。思路就是建立一个数组,由上向下动态规划,保存上节点到叶节点的最大值
记忆化搜索法:
#include<stdio.h> //0ms AC
#include<string.h>
int map[105][105],d[105][105],n;
int dis(int i,int j){
if(d[i][j]>=0) return d[i][j];
return d[i][j]=map[i][j]+(i==n ? 0 : (dis(i+1,j)>dis(i+1,j+1)?dis(i+1,j):dis(i+1,j+1)));
}
int main()
{
int i,j;
scanf("%d",&n);
memset(d,-1,sizeof(d));
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
scanf("%d",&map[i][j]);
printf("%d\n",dis(1,1));
return 0;
}
好吧,还有个递推计算法,从下往上的
#include<stdio.h> //16ms AC
int map[105][105],d[105][105];
int main()
{
int n,i,j;
scanf("%d",&n);
for(i=0;i<n;i++)
for(j=0;j<=i;j++)
scanf("%d",&map[i][j]);
for(i=0;i<n;i++) d[n-1][i]=map[n-1][i];
for(i=n-2;i>=0;i--)
for(j=0;j<=i;j++)
d[i][j]=map[i][j]+(d[i+1][j]>d[i+1][j+1]?d[i+1][j]:d[i+1][j+1]);
printf("%d\n",d[0][0]);
return 0;
}