動態規劃演算法 數字三角形問題

2021-06-29 02:25:01 字數 1095 閱讀 3067

問題描述:

有乙個有非負整數組成的三角形,第一行只有乙個數,除了最下行之外的每個數的左下方和右下方各有乙個數。如下圖:

從第一行的數字開始每次可以向左走或者向右走,直到走到最下行,把沿途經過的所有數字全部加起來,如何走才能使這個和最大?

1.        回溯法:可以求出所有的路線,然後從所有的路線中選擇最好的,但是效率太低。

2.        動態規劃:

1)        把當前的位置(i,j)看成乙個狀態,定義狀態(i,j)的指標函式d(i,j)為從(i,j)出發時能得到的最大和(包括(i,j)本身的值)。原問題的解是:d(1,1)。

2)        狀態轉移:d(i,j)=a(i,j)+max.

3)        遞迴程式實現:程式簡潔,但是效率低,因為存在大量重複計算的節點。

int solve(int i,int j)

return a[i][j]+(i==n? 0 : max(solve(i+1,j),solve(i+1,j+1)));

4)        遞推程式實現:時間複雜度為o(n^2),最下面一行單獨處理後,從下至上逆序列舉每一行。

int i,j;

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

d[n][j]=a[n][j];

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

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

d[i][j]=a[i][j]+max(d[i+1][j],d[i+1][j+1]);//d[i+1][j],d[i+1][j+1]已經先於d[i][j]計算出

5)        記憶化搜尋:不必事先確定各狀態的計算順序,但需要記錄每個狀態「是否計算過」。

memset(d,-1,sizeof(d));

int solve(int i,int j)

if(d[i][j]>=0)

return d[i][j];

return d[i][j]=a[i][j]+(i==n ? 0 : max(solve(i+1,j), solve(i+1,j+1)) );

程式依然是遞迴的,但是能避免重複訪問節點。因為所有的數字非負,那麼已經算出的結點就應該是非負的,首先清空狀態函式為-1,若不小於0,那麼不用再計算。

動態規劃 數字三角形問題

數字三角形問題 time limit 1000ms memory limit 65536kb problem description 給定乙個由n行數字組成的數字三角形如下圖所示。試設計乙個演算法,計算出從三角形的頂至底的一條路徑,使該路徑經過的數字總和最大。對於給定的由n行數字組成的數字三角形,計...

動態規劃 數字三角形問題

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

動態規劃 數字三角形問題

problem description 給定乙個由n行數字組成的數字三角形如下圖所示。試設計乙個演算法,計算出從三角形的頂至底的一條路徑,使該路徑經過的數字總和最大。對於給定的由n行數字組成的數字三角形,計算從三角形的頂至底的路徑經過的數字和的最大值。input 輸入資料的第1行是數字三角形的行數n...