The Triangle
Problem Description
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
(Figure 1)
图 1 显示了一个数字三角形。编写一个程序,计算从顶部开始并在基座上某处结束的路线上传递的最高数字总和。每个步骤都可以对角向左向下,也可以对角线向下到右侧。
输入
您的程序是从标准输入读取。第一行包含一个整数 N:三角形中的行数。以下 N 行描述三角形的数据。三角形中的行数为 > 1,但 <= 100。三角形中的数字(所有整数)介于 0 和 99 之间。
输出
您的程序是写入标准输出。最高总和以整数编写。
示例输入
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
样品输出
30
来源
北大
之前是将所可能的路线都计算一遍,如果都计算一次的话,那就要计算2的n次方次,在排序输出最大值,那么涉及将每一个线路节点更新的数值保存,内存大。那么可以考虑选取可选择范围内最小值。使得每一步的数值最小,之前是在最后一层向第一层递进,但是要换下标和控制列的取值,
dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+a[i][j];
发现这样把自己都绕进去了。。。看了其他程序明白了。这个应该从倒数第二行开始,
如上d[i][j]的值就是,比较其中两个数中较大的那一个,再加上本身的值完成更新数据值a[i][j]
从第n行把状态一直更新到第一行,那dp[1][1]就是我们所要求的值。
后来还出现了Runtime Error,
在G++编译器main函数必须返回整数0,如果返回1被操作系统认为是不正常结束的还是会出现Runtime Error.
后来将数组设置成了全局变量解决了。
在处理问题的时候一定要考虑边界,没考虑边界导致漏了数据没有算上去。
ac代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int n,a[100][100],dp[100][100];
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
scanf("%d",&n);
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
scanf("%d",&a[i][j]);
}
}
int sum=1;
for(int i=n;i>=0;i--)//注意边界
{
for(int j=1;j<=i;j++)
{
dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+a[i][j];//更新,处理边界问题之前没考虑每一次要更新上一层的数值,
//还有可以从上置底
}
}
printf("%d\n",dp[1][1]);
return 0;
}