題目描述
考慮在下面被顯示的數字金字塔。 寫一個程序來計算從最高點開始在底部任意處結束的路徑經過數字的和的最大。每一步可以走到左下方的點也可以到達右下方的點。
在上面的樣例中,從7 到 3 到 8 到 7 到 5 的路徑產生了最大和:30
輸入
第1行:1個整數R(1<= R<=1000),表示行的數目。
接下來共R行,第i行有i個整數。所有的數均非負的且不大於100。
輸出
第1行:可以得到的最大的和。
樣例輸入
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
樣例輸出
30
【分析】
這一題如果用貪心法來做,有可能得不到最優解。如果用枚舉,列舉的路徑會有很多。所以可以用動態規劃來解題。
因爲只能走左下或右下,所以只需要判斷走哪一邊能使數之和最大。走了那一邊之後又到了一個新點,再判斷走哪邊能使數之和最大。所以,只需要從底層開始,層層遞進,最後得到最大值。
狀態:Nowmax[i][j]:第i排第j個出發所能得到的最大值。
Number[i][j]:第i排第j個表示的數。
狀態轉移方程:Nowmax[i][j]=max(Nowmax[i+1][j],Nowmax[i+1][j+1])+Number[i][j];
#include<cstdio>
#include<algorithm>//使用max(x,y)函數所需要的頭文件
using namespace std;
const int SZ=1005;//定義一個常量SZ表示數組大小
int Nowmax[SZ][SZ],Number[SZ][SZ],Sum;
//Sum表示層數,Nowmax表示從當前點出發所能得到的最大和
//Number表示當前點表示的數
int main()
{
scanf("%d",&Sum);
for(int i=1;i<=Sum;i++)
for(int j=1;j<=i;j++)
scanf("%d",&Number[i][j]);//輸入
for(int i=Sum;i>=1;i--)//從底層向上計算
for(int j=1;j<=i;j++)
Nowmax[i][j]=max(Nowmax[i+1][j],Nowmax[i+1][j+1])+Number[i][j];
//轉移狀態時別忘了加上本身這個數
printf("%d\n",Nowmax[1][1]);//輸出
return 0;
}