動態規劃 數字三角形

2021-09-27 22:24:17 字數 3371 閱讀 1612

學習演算法,個人覺得還是對照著例題來理解效果做好,演算法概念太學術味太濃,個人不太喜歡。今天介紹乙個動態規劃入門例題。這道題來自北大的poj。題目如下:

數字三角形(poj1163)

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

輸入格式:

5      //表示三角形的行數    接下來輸入三角形

7

3   8

8   1   0

2   7   4   4

4   5   2   6   5

要求輸出最大和

我們來分析一下這道題該怎麼做

首先肯定要乙個二維陣列來存放三角形

然後我們用d( r, j)來表示第r行第j個數字(r , j1開始算)

我們用maxsum(r,j)表示d(r,j)到底邊各條路徑的最大值

最後就是要求d(1,1)

我們可以用遞迴來求解

d(r,j)出發,下一步只能走d(r+1,j)d(r+1,j+1)  ,可以得到如下遞迴式

if ( r == n)                

maxsum(r,j) = d(r,j)

else

maxsum( r, j) = max + d(r,j)

由上述遞迴式可以得到如下的**:

#include#includeusing namespace std;

int d[50][50];

int n;

int dp(int r, int j)

int x = dp(r + 1, j);

int y = dp(r + 1, j + 1);

return max(x, y) + d[r][j];

}int main()

} cout << dp(1, 1) << endl;

system("pause");

return 0;

}

不過這段**中有很多重複計算的地方,看圖

當計算7的時候,要往下依次遞迴計算3、8,計算3的時候要遞迴計算8、1,計算8(7下面右邊 那個)的時候又要計算一次1,其它的以此類推。這要就導致了很多不必要的重複計算,我們可以保留這些計算結果作為判斷是否計算過的依據,

改進過後的**如下:

#include#includeusing namespace std;

int d[50][50];

int maxsum[50][50];

int n;

int dp(int r, int j)

if (r == n)

else

return maxsum[r][j];

}int main()

} cout << dp(1, 1) << endl;

system("pause");

return 0;

}

因為遞迴總是需要使用大量堆疊上的空間,很容易造成棧溢位,我們現在就要考慮如何把遞迴轉換為遞推,讓我們一步一步來完成這個過程。

**如下:

#include#includeusing namespace std;

int d[50][50];

int maxsum[50][50];

int n;

int main()

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

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

} cout << maxsum[1][1] << endl;

system("pause");

return 0;

}

到這裡是不是覺得已經到極致了?錯,還可以繼續優化,不過不是時間上的優化,是空間上的優化,我們可以只用乙個一維陣列來記錄已經得到的值。只要從底層一行行向上遞推,那麼只要一維陣列maxsum[100]即可,即只要儲存一行的maxsum值就可以。看圖。

依照上面的方式,我們可以寫出如下**: 

#include#includeusing namespace std;

int d[50][50];

int maxsum[50];

int n;

int main()

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

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

} cout << maxsum[1] << endl;

system("pause");

return 0;

}

至此,該問題已經是最優了。

如有錯誤,請指正。

動態規劃 數字三角形

如圖所示的數字三角形,從頂部出發,在每一結點可以選擇向左走或得向右走,一直走到底層,要求找出一條路徑,使路徑上的值最大。第一行是數塔層數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 三角形行數。下面是三...

動態規劃 數字三角形

在用動態規劃解題時,我們往往將和子問題相關的各個變數的一組取值,稱之為乙個 狀態 乙個 狀態 對應於乙個或多個子問題,所謂某個 狀態 下的 值 就是這個 狀態 所對應的子問題的解。以 數字三角形 為例,初始狀態就是底邊數字,值就是底邊數字值。定義出什麼是 狀態 以及在該 狀態 下的 值 後,就要找出...