Description
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
(Figure 1)
Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.
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
思路
动态规划。定义一个f二维数组,f[i][j]代表从第i行第j列到达低端的最大值。
初始先将低端的值初始化给f数组
转移方程 f[i][j]=max(f[i+1][j],f[i+1][j+1])+w[i][j]
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int w[101][101];
int f[101][101];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
scanf("%d",&w[i][j]);
for(int i=1;i<=n;i++)
f[n][i]=w[n][i];
for(int i=n-1;i>0;i--)
for(int j=1;j<=i;j++)
f[i][j]=max(f[i+1][j],f[i+1][j+1])+w[i][j];
cout<<f[1][1];
return 0;
}
优化
可以f不用二维数组,用一维数组也行,因为每一次计算只需其下一行的值,可以计算出这行的数将下一行覆盖。
此题数据量较小,优化效果不明显
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int w[101][101];
int f[101];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
scanf("%d",&w[i][j]);
for(int i=1;i<=n;i++)
f[i]=w[n][i];
for(int i=n-1;i>0;i--)
for(int j=1;j<=i;j++)
f[j]=max(f[j],f[j+1])+w[i][j];
cout<<f[1];
return 0;
}
另外,也可不用f数组,就直接将数据存在w数据数组的底行
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int w[101][101];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
scanf("%d",&w[i][j]);
for(int i=n-1;i>0;i--)
for(int j=1;j<=i;j++)
w[n][j]=max(w[n][j],w[n][j+1])+w[i][j];
cout<<w[n][1];
return 0;
}