動態規劃(dynamic programming)網上大家都簡稱爲DP。DP的核心思想就是找出各階段各子問題之間的關係,然後利用各階段的關係逐個求解。其中比較經典的題目就是數塔和最長有序子序列的求解。
數塔
題目 :有形如下面所示的數塔,從頂部出發,在每一節點可以選擇向左走或是向右走,一直走到底層,需求找出一條路徑,使路徑上的值最大。
解題思路路:從頂點出發時到底向左走還是向右走應取決於是從左走能取到最大值還是從右走能取到最大值,只要左右兩道路徑上的最大值求出來了才能作出決策。同樣,下一層的走向又要取決於再下一層上的最大值是否已經求出才能決策。這樣一層一層推下去,直到倒數第二層時就非常明瞭。如數字2,只要選擇它下面較大值的結點19前進就可以了。所以實際求解時,可從底層開始,層層遞進,最後得到最大值。
結論:自頂向下的分析,自底向上的計算。
如圖創建這樣一個數組記錄該點目前爲止距離底層最長的距離。然後其上一層可以經過簡單比較得出所求。得出答案爲:59!
59
50 49
38 34 29
21 28 19 21
19 7 10 4 16
代碼如下:
TIME:484MS //由於是O(n^2)的複雜度所以MS略高。
MEM;352K
#include <iostream>
using namespace std;
int main()
{
int c;
cin>>c;
short sum[101][100];
while(c--)
{
int N;
cin>>N;
for(int i=1; i<=N; i++)
{
for(int j=1; j<=i; j++)
cin>>sum[i][j];
}
short max;
for(int i=N-1;i>=1;i--)
{
max = 0;
for(int j=1; j<=i; j++)
{
max = sum[i+1][j]>sum[i+1][j+1]?sum[i+1][j]:sum[i+1][j+1];
sum[i][j] += max;
}
}
cout<<sum[1][1]<<endl;
}
return 0;
}