動態規劃初步 數字三角形

2021-08-18 18:45:32 字數 1501 閱讀 2913

問題描述:

有乙個由非負整數組成的三角形,第一行只有乙個數,除了最下行之外每個數的左下方和右下方各有乙個數。從第一行的數開始,每次可以往左下或右下走一格,直到走到最下行,把沿途經過的數全部加起來,如何走才能使得這個和盡量大

若熟悉回溯法,會發現這是個動態的決策問題:每次有兩種選擇—左下或右下。若用回溯法求出所有可能的路線,便可從中找出最優路線,但這樣做的效率很低:乙個n層數字三角形的完整路線有2^n-1條,當n很大時回溯法的

速度將讓人無法忍受

那麼,從格仔(i,j)出發有兩種決策,如果往左走,最好情況是(i,j)格仔中的值與"從(i+1,j)出發的最大總和"之和,同理,如果往右走,最好情況是(i,j)格仔中的值與「從(i+1,j+1)出發的最大總和」之和

相應狀態轉移方程:d(i,j)=a(i,j)+max( d(i+1,j) , d(i+1,j+1) )

方法一:(遞迴計算)(**中的n為三角形層數,二維陣列a中儲存了三角形各個位置的數字)

int solve(int i,int j)
該方法可行但時間效率太低,原因是相同的子問題會被重複計算多次

方法二:遞推計算(需注意邊界處理)

int i,j;  

for(i=1;i<=n;i++)

for(i=n-1;i>=1;i--)

}

方法三:記憶化搜尋

將計算結果儲存在陣列d中,題目已知三角形中每個數均非負,故先將d中所有元素初始化為-1,若已計算過某個d[i][j],則它應是非負的,可以保證每個結點只訪問一次。

int solve(int i,int j)
最終**:

//方法一  

#include#includeusing namespace std;

const int maxn=105;

int array[maxn][maxn];

int d[maxn][maxn];

int n;

int main()

} for(i=1;i<=n;i++)

for(i=n-1;i>=1;i--)

} cout

const int maxn=105;

int array[maxn][maxn];

int d[maxn][maxn];

int n;

int solve(int i,int j)

int main()

} solve(1,1);

cout<

return 0;

}

動態規劃初步 數字三角形

從上往下求和,求最大和的路徑.3 2 4 10 1 分析 從下向上求和 附 和執行結果 遞推計算和遞迴求和,它們都會把前一步的計算結果儲存下來 樹 好吧我蛋疼了.這裡面用佇列來逐層build和print.這個才更像重點 v typedef struct node node node root nod...

動態規劃 數字三角形

如圖所示的數字三角形,從頂部出發,在每一結點可以選擇向左走或得向右走,一直走到底層,要求找出一條路徑,使路徑上的值最大。第一行是數塔層數n 1 n 100 第二行起,按數塔圖形,有乙個或多個的整數,表示該層節點的值,共有n行。輸出最大值。5 1311 8 12 7 26 6 14 15 8 12 7...

動態規劃 數字三角形

7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 在上面的數字三角形中尋找一條從頂部到底邊的路徑,使得 路徑上所經過的數字之和最大。路徑上的每一步都只能往左下或 右下走。只需要求出這個最大和即可,不必給出具體路徑。三角形的行數大於1小於等於100,數字為 0 99 5 三角形行數。下面是三...