初識DP動態規劃

一、多階段決策過程的最優化問題
在現實生活中,有類活 動的過程,由於 它的特殊性,可將過程分成若干個互相階段。在它的每一階段都需要作出決策,從而使整個過程達到最好的活動效果。當階段決策的選取不是任意確定的,它依賴於當前面臨的狀態,又影響以後的發展,當段決策確定後,就組成一個決策序列,因而也就確定了整個過程的一條活動路線,這個問題看作是個前後關聯具有鏈狀結構的 多階段過程就稱爲多階段決策過程,這就稱爲多階段決策問題。
多階段決策過程,是指這樣的一類特殊的活動過程,問題可以按時間順序分解互聯繫的階段,在每-個階段都要作出決策,全部過程的決策是-個決策序列。

二、能採用動態規劃求解的問題的一般要具有3個性質:
最優化原理:如果問題的最優解所包含的子問題的解也是最優的,就稱該問題具有最優子結構,即滿足最優化原理。
無後效性:即某階段狀態一旦確定,就不受這個狀態以後決策的影響。也就是說,某狀態以後的過程不會影響以前的狀態,只 與當前狀態有關。
有重疊子問題:即子問題之間是不獨立的,一個子問題在下一階段決策中可能被多次使用到。(該性質並不是動態規劃適用的必要條件,但是如果沒有這條性質,動態規劃算法同其他算法相比就不具備優勢)

三、動態規劃基本概念
狀態:描述事物的性質,不同事物有不同的性質,因而用不同的狀態來刻畫。對問題的求解狀態的描述是分階段的。
決策:根據題意要求,對每個階段所做出的某種選擇性操作。
狀態轉移方程:用數學公式描述與階段相關的狀態間的演變規律。
四、解題步驟:

  1. 拆分問題
  2. 定義狀態(並找出初狀態)
  3. 狀態轉移方程

五、模型方法
第一種遞歸搜索法。
第二種遞歸搜索法+記憶。
第三種遞推式法。

六、例題
數塔問題
在這裏插入圖片描述
思路分析:
貪心不可解,每一步都會影響後續的操作。
在用動態規劃考慮數塔問題時可以自頂向下的分析,自底向上的計算。
從頂點出發時到底向左走還是向右走應取決於是從左走能取到最大值還是從右走能取到最大值,只要左右兩道路徑上的最大值求出來了才能作出決策。同樣的道理下一層的走向又要取決於再下一層上的最大值是否已經求出才能決策。這樣一層一層推下去,直到倒數第二層時就非常明瞭。
所以第一步對第五層的8個數據,做如下四次決策:
如果經過第四層2,則在第五層的19和7中肯定是19;
如果經過第四層18,則在第五層的7和10中肯定是10;
如果經過第四層9,則在第五層的10和4中肯定是10;
如果經過第四層5,則在第五層的4和16中肯定是16;
經過一次決策,問題降了一階。5層數塔問題轉換成4層數塔問題,如此循環決策…… 最後得到1階的數塔問題。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100+10;
int num[MAXN][MAXN];
int dp[MAXN][MAXN];
int main()
{
    int t;
    scanf("%d", &t);
    while( t-- )
    {
        memset(dp, 0, sizeof(dp));
        int n;
        scanf("%d", &n);
        for( int i=1; i<=n; i++ )
        {
            for( int j=1; j<=i; j++ )
                scanf("%d", &num[i][j]);
        }
        for( int j=1; j<=n; j++ )
            dp[n][j] = num[n][j];
        for( int i = n-1; i >= 1; i-- )
        {
             for( int j=1; j <= i; j++ )
             {
                 dp[i][j] = num[i][j] + max(dp[i+1][j], dp[i+1][j+1]);
             }
        }
        printf("%d\n", dp[1][1] );
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章