【問題描述】
觀察下面的數字金字塔。寫乙個程式查詢從最高點到底部任意處結束的路徑,使路徑經過數字的和最大。每一步可以從當前點走到左下方的點也可以到達右下方的點。
在上面的樣例中,從13到8到26到15到24的路徑產生了最大的和86。
【樣例輸入】
第乙個行包含r(1≤ r≤1000),表示行的數目。後面每行為這個數字金字塔特定行包含的整數。所有的被**的整數是非負的且不大於100。
【樣例輸出】
單獨的一行,包含那個可能得到的最大的和。
【動態規劃問題分析思路】
此問題是「最值型」問題,適用於利用動態規劃方法解決。
步驟如下:
1.確定狀態
■ 研究最優策略的最後一步
■ 化為子問題
■ 注意:狀態在動態規劃中的作用屬於定海神針
2.狀態轉移方程
■ 根據子問題定義直接得到
3.初始條件和邊界情況
■ 細心,考慮周全
■ 注意:不能通過狀態轉移方程計算出的值設為初始條件
4.計算順序
■ 原則是利用之前的計算結果。故可依據狀態轉移方程確定計算順序。 上述分析思路詳見:
【本題利用最後一步法的解題思路】
將金字塔拉伸為如圖所示形狀,更便於分析。
最後一步:從最高點到底部任意處(i,j)時,路徑所經過的數字和最大。
子問題:從最高點到(i-1,j-1)處所經過的數字和最大值,及從最高點到(i-1,j)處所經過的數字和最大值的較大值加上(i,j)處結點的值。
狀態:設f[i][j]表示從最高點到(i,j)路徑所經過的數字和的最大值。
狀態轉移方程:f[i][j]=max(f[i-1][j-1],f[i-1][j])+a[i][j]; -->a[i][j]表示結點(i,j)的值,即圖中圓圈中的值。
初始條件:f[1][1]=a[1][1]; -->因為此分析過程將二維陣列的兩個維度的下標都從1開始,所以f[1][1]不能通過上面確定的狀態轉移方程計算出來,所以必須明確指定。
計算順序:自動依據狀態轉移方程確定。
【演算法**】
#include using namespace std;
const int maxn=1005;
const int inf=0x3f3f3f3f;
int a[maxn][maxn];
int f[maxn][maxn];
int ans=-inf;
int main()
} for(int i=1; i<=n; i++)
} f[1][1]=a[1][1];
for(int i=2; i<=n; i++)
} for(int i=1; i<=n; i++)
cout上述**是從上往下分析得出的結果。若從下往上分析,則**為:
#includeusing namespace std;
const int maxn=505;
int a[maxn][maxn];
int f[maxn][maxn];
int n;
int main()
} for(int i=n; i>=1; i--)
} cout<
【參考文獻】
動態規劃2 例9 2數字金字塔
例9.2數字金字塔 觀察下面的數字金字塔。寫乙個程式查詢從最高點到底部任意處結束的路徑,使路徑經過數字的和最大。每一步可以從當前點走到左下方的點也可以到右下方的點方法一 從最高點按照規則走到最低點的路徑的最大的權值和,路徑起點終點固定,走法規則明確,可以考慮用搜尋演算法 定義遞迴函式 void df...
數字金字塔 一維,順推)
題目 description 你和權權是一對很好很好的朋友。有一天,你們無聊得很,便上網衝浪,突然在乙個叫做usaco的網中找到了乙個遊戲 數字金子塔 遊戲規則是這樣的 求乙個數字金字塔中從最高點開始在底部任意處結束的路徑經過數字的和的最大,其中的每一步可以走到下方的點也可以到達右下方的點。例如在下...
一本通1258 例9 2 數字金字塔
原題傳送門 0.前言 顯然,這是一道動態規劃 dp 的入門題,也是一道非常經典的例題。1.思路 dp 和貪心主要就不同在 dp 求全域性最優解,貪心求區域性最優解 這道題顯然不是用貪心來做,因為當前的區域性最優解可以不是全域性最優解 solution 1 逆推 首先輸入乙個三角形樣的三角形 for ...