1. 程式人生 > >數字金字塔(逆推)【DP】

數字金字塔(逆推)【DP】

> Description
考慮在下面被顯示的數字金字塔。
寫一個程式來計算從最高點開始在底部任意處結束的路徑經過數字的和的最大。
每一步可以走到左下方的點也可以到達右下方的點。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
在上面的樣例中,從7 到 3 到 8 到 7 到 5 的路徑產生了最大和:30

> Input
第一個行包含 R(1<= R<=1000) ,表示行的數目。
後面每行為這個數字金字塔特定行包含的整數。
所有的被供應的整數是非負的且不大於100。

> Output
單獨的一行包含那個可能得到的最大的和。

> Sample Input


5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

> Sample Output
30

> 解題思路
copy一下老師的ppt
動態規劃的幾個特性:
可以使用動態規劃的題目特點
一個大問題可以劃分為若干個子問題
最優子結構
子問題: 性質一樣但是規模變小的問題
在計算時子問題有重疊
重疊子結構

動態規劃高效的原理:
重複的子問題不重複處理)

所以這一道題就把每個節點下面的數和右下角的都進行了比較。從第r行開始一直到第一行,把一行中的每一個數進行判斷和累加。
每一層為一個階段,每i層的狀態為i,每一個的決策為2。

#include<iostream>
#include<cstdio> const int maxn=10001; int r,a[maxn][maxn],f[maxn][maxn]; int ooo(int s,int t) { if(s>t) return s; return t; }//這裡是因為max不知道為什麼突然用不了了,所以就定義了一個函式 int main() { int x,y; scanf("%d",&r); for(x=1;x<=r;x++) for(y=1;y<=x;y++) scanf("%d",&a[x][y]); for(x=r;x>
0;x--) for(y=1;y<=x;y++) f[x][y]=ooo(f[x+1][y],f[x+1][y+1])+a[x][y]; //判斷 printf("%d",f[1][1]); return 0; }