數塔問題是二維情況下動態規劃的經典問題,下面以洛谷的乙個例題來分析數塔問題以及動態規劃:原題鏈結
題目描述
觀察下面的數字金字塔。寫乙個程式來查詢從最高點到底部任意處結束的路徑,使路徑經過數字的和最大。每一步可以走到左下方的點也可以到達右下方的點。輸入格式在上面的樣例中,從7→3→8→7→5 的路徑最大
第乙個行乙個正整數 rr ,表示行的數目。後面每行為這個數字金字塔特定行包含的整數。輸出格式
單獨的一行,包含那個可能得到的最大的和。樣例輸入
5樣例輸出 資料範圍73 8
8 1 0
2 7 4 4
4 5 2 6 5
對於100%的資料,1 ≤ r ≤ 1000,所有輸入在 [0,100] 範圍內。數塔問題遞迴寫法分析:遞迴寫法**:
#include
#include
#include
#include
using
namespace std;
const
int n =
1010
;int a[n]
[n];
//儲存資料
int n;
//遞迴函式中需要設定邊界,故將n設為全域性變數
intdfs
(int x,
int y)
//x表示行,y表示列
intmain()
當然,當資料範圍很大時,由於遞迴寫法的重疊子問題太多,所以又見到了熟悉的tle… …話不多說直接上圖
下面給出本題的ac**:
#include
#include
#include
#include
using
namespace std;
const
int n =
1010
;int a[n]
[n];
//儲存數塔
int f[n]
[n];
//表示從第i行第j列到第n行的最大路徑
int n;
intmain()
return0;
}
動態規劃的基本思想:將待求解問題分解成若干個子問題,先求解子問題,然後從這些子問題的解得到原問題的解。我們需要儲存已解決的子問題的答案,這樣可以避免大量的重複計算,節省時間。我們會用乙個表來記錄所有已解的子問題的答案。不管該子問題以後是否被用到,只要它被計算過,就將其結果填入表中,而在需要時再找出已求得的答案。
換個新數塔哈~
如上圖所示,若想找到這個8層數塔的最長路徑,即將問題描述為:
以此類推,不難發現,從紅色位置開始找出一條最長路徑,這個問題依賴於很多個子問題,而這些子問題構成了綠色部分。
我們只需要計算出①②兩個子問題的答案,選擇其中較大的值,再加上第一行第一列的那個數字,就可以得到數塔的最長路徑。
由以上分析,得出狀態轉移方程:
dp[i]
[j]= max
+ a[i]
[j]邊界:當i > n時,f[i]
[j]=
0;
下面再給出數塔的乙個例題
原題鏈結
ac**:
#include
#include
#include
#include
using
namespace std;
const
int n =
1010
;int a[n]
[n];
//儲存數塔
int f[n]
[n];
//表示從第i行第j列到第n行的最大路徑
int n;
intmain()
return0;
}
動態規劃 數塔問題
有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?從頂點出發時到底向左走還是向右走應 取決於是從左走能取到最大值還是從右走能取到最大值,只要左右兩道路徑上的最大值求出來了才能作出決策。同樣的道理下一層的走向又要取決於再下一層上的最大值是否已經求出才能...
動態規劃 數塔問題
從上到下出發,每次只能走到下面相鄰的節點,尋找一條路徑使經過的數值和最大。12 15 10 6 8 2 18 9 5 19 7 10 4 15 動態規劃思路 假設到第i行第j個元素為止的最優解為f i j 則f i j 實際上至於f i 1 j 和f i 1 j 1 有關。include inclu...
數塔問題(動態規劃)
設有乙個三角形的數塔,頂點為根結點,每個結點有乙個整數值。從頂點出發,可以向左走或向右走,如圖所示 若要求從根結點開始,請找出一條路徑,使路徑之和最大,只要輸出路徑的和。輸入第一行為n n 10 表示數塔的層數 從第2行至n 1行,每行有若干個資料,表示數塔中的數值。輸出 輸出路徑和最大的路徑值。樣...