問題描述:考慮下面的數字金字塔,寫乙個程式來計算從最高點開始,在底部任意處結束經過的數字和最大,每一步可以走到左下和右下的點。
73 8
8 1 0
2 7 4 4
4 5 2 6 5
變形後:
3 8
8 1 0
2 7 4 4
4 5 2 6 5
問題分析:可以先對金字塔進行變形,如上。對於數字金字塔可以用(i, j)來表示數字在金字塔中的位置。
對於金字塔中間的一點,想要經過它,則必須經過它的左上或上面的點(變形後)。因此要使經過該點的和最大,則是在經過左上和右上的點中較大的「最大和」,
然後加上該點的值。這樣,狀態很明顯是金字塔的層。
設計乙個二維狀態opt[i, j]表示到第 i 行 第 j 列的最大和,那麼決策就是opt[i-1, j-1]和opt[i-1, j]中較大值在加上(i, j)處的值。
狀態轉移方程為:
opt[i, j] = opt[i-1, j] + a[i, j] j=1 //左邊緣
opt[i, j] = opt[i-1, j-1] + a[i, j] j=i //右邊緣
opt[i, j] = max + a[i, j]; 1最後的答案:ans = max 1 <= i <= n;
還有一點就是:其實從上往下和從下往上走是一樣的,從下往上走時,可以省下求最大值的步驟,最終結果就是opt[1,1],狀態方程為:
opt[i, j] = max + a[i, j] ;
測試**:
#include
<
stdio.h
>
#include
<
stdlib.h
>
intmain(),,
,,};int
opt[5][
5];inti, j;
for(i=0
; i<
5; i++)
opt[
4][i] =a[
4][i];
//初始化最後一行
for(i=3
; i>=
0; i--)
for(j=0
; j<=
i; j++)
if(opt[i+1
][j]
>
opt[i+1
][j+1])
opt[i][j]
=opt[i+1
][j]
+a[i][j];
else
opt[i][j]
=opt[i+1
][j+1]
+a[i][j];
printf(
"max:%d\n
", opt[0][
0]);
return0;
}
DP數塔問題
有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?有一組測試樣例,測試例項的第一行是乙個整數n 1 n 100 表示數塔的高度,接下來用n行數字表示數塔,其中第i行有個i個整數,且所有的整數均在區間 0,99 內。output 對於每個測試例項,輸出...
DP經典問題,數塔
在講述dp演算法的時候,乙個經典的例子就是數塔問題,它是這樣描述的 有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?dp問題一般都是從後向前,後文有從前向後的動態規劃 分析 因為要找到最大值的連線,我們可以從倒數第二行開始,在2時可以選擇19和7,...
DP 1 數塔問題
數塔問題 基本模型 如上圖所示數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?數塔思想 自頂向下分析,自底向上計算。h i 表示第i層的最大值。要得到h i 1 則考慮上一層結點,到其相鄰節點可取得的值,取最大值作為h i 1 如果按照上述做法,從頂到底算起,...