動態規劃演算法

2021-09-23 21:08:49 字數 2400 閱讀 7287

斐波納契數列f(n)

遞迴 vs 動態規劃

遞迴版本(太慢):

int f(int n)

動態規劃版本(有效率!演算法複雜度是 o(n)):

int a[1000];

int f(int n)

構造乙個公式,它表示乙個問題的解是與它的子問題的 解相關的公式.   e.g.  f(n) = f(n-1) + f(n-2).

為這些子問題做索引 ,以便它們能夠在表中更好的儲存與檢索 (i.e., 陣列array)

以自底向上的方法來填寫這**; 首先填寫最小子問題的解.

這就保證了當我們解決乙個特殊的子問題時, 可以利用比它更小的所有可利用的 子問題的解.

演算法思想:

將待求解的問題分解成若干個子問題,並儲存子問題的解而避免計算重複的子問題,並由子問題的解得到原問題的解。

動態規劃演算法通常用於求解具有某種最優性質的問題。

動態規劃演算法的基本要素:最優子結構性質和重疊子問題。

原理:重疊子問題:在用遞迴演算法自頂向下解問題時,每次產生的子問題並不總是新問題,有些問題被反覆計算多次。對每個子問題只解一次,然後將其解儲存起來,以後再遇到同樣的問題時就可以直接引用,不必重新求解。

解決問題的基本特徵:

1. 動態規劃一般解決最值(最優,最大,最小,最長……)問題;

2. 動態規劃解決的問題一般是離散的,可以分解(劃分階段)的;

3. 動態規劃解決的問題必須包含最優子結構,即可以由(n-1)的最優推導出n的最優

解決問題的基本步驟:

動態規劃演算法的4個步驟:

1. 刻畫最優解的結構特性. (一維,二維,三維陣列)

2. 遞迴的定義最優解. (狀態轉移方程)

3. 以自底向上的方法來計算最優解.

4. 從計算得到的解來構造乙個最優解.

例題一.   斐波納契數列f(n)

步驟1:用f(n)表示在斐波納契數列中第n個數的值;

步驟2:狀態轉移方程:

步驟3:以自底向上的方法來計算最優解

nf(n)

步驟4:在陣列中分析構造出問題的解;

例題二.   輸入n,求出n!

步驟1:用f(n)表示n!的值;

步驟2:狀態轉移方程:

步驟3:以自底向上的方法來計算最優解

nf(n)

例題三:排隊買票問題

一場演唱會即將舉行。現有n個歌迷排隊買票,乙個人買一張,而售票處規定,乙個人每次最多只能買兩張票。假設第i位歌迷買一張票需要時間 ti(1≤i≤n),隊伍中相鄰的兩位歌迷(第j個人和第j+1個人)也可以由其中乙個人買兩張票,而另一位就可以不用排隊了,則這兩位歌迷買兩張票的時 間變為rj,假如rj分析:

如果前i個人買票的最優買票方式一確定,比如第i-1個人買一張票,則前i-1個人的買票方式也一定是最優的。即問題的最優解包含子問題的最優解。

步驟1:用f(i)表示前i個人買票的最優方式,即所需最短時間;現在要決定f(i)需要考慮兩種情況:

(1)第i個人的票自己買

(2)第i個人的票由第i-1個人買

步驟2:狀態轉移方程:

步驟3:以自底向上的方法來計算最優解

程式的實現(偽**):

buyticks(t, r)

1 n ← length[t]

2 f[0] ← 0

3 f[1] ← t[1]

4for i ← 2 to n do

5 f[i] ← f[i-2]+r[i-1]

6if f[i] > f[i-1]+t[i] then

7 f[i] ← f[i-1]+t[i]

8return f

動態規劃演算法

一 動態規劃演算法原理 將待求解的問題分解成若干個相互聯絡的子問題,先求解子問題,然後從這些子問題的解得到原問題的解 對於重複出現的子問題,只在第一次遇到的時候對它進行求解,並把答案儲存起來。了不去求解相同的子問題,引入乙個陣列,把所有子問題的解存於該陣列中,這就是動態規劃所採用的基本方法。動態規劃...

動態規劃演算法

動態規劃 通過把原問題分解為相對簡單的子問題來求解複雜問題。動態規劃常常適用於有重疊子問題和最優子結構性質的問題。演算法總體思想 演算法的基本步驟 演算法的基本要素 最優子結構 重疊子問題 備忘錄方法 問題描述 子串行 公共子串行 最長公共子串行 lcs 問題 問題分析 動態規劃求解lcs問題 最長...

動態規劃演算法

動態規劃演算法的思路 動態規劃法即 dynamic programming method dp 是系統分析中的種常用方法。動態規劃法是20世紀50年代由貝爾曼 r.bellman 等人提出的,用來解決多階段決策過程問題的一種最優化方法。多階段決策過程是指把研究問題分成若干個相互聯絡的階段,由每個階段...