動態規劃 一

2021-07-10 05:05:53 字數 1368 閱讀 4607

在現實生活中,有一類活動的過程,由於它的特殊性,可將過程分程若干個互相聯絡的階段,在它的每一階段都需要作出決策,從而使整個過程達到最好的活動效果。當然,各個階段決策的選取不是任意確定的,它依賴於當前面臨的狀態,又印象以後的發展,當各個階段決策確定後,就組成乙個決策序列,因而也就確定了整個過程的一條活動路線,這種把乙個問題看作是乙個前後關聯具有連莊結果的多階段過程就稱為多階段決策過程,這種問題就稱為多階段決策問題。

動態規劃過程:每次決策依賴於當前狀態,又隨即引起狀態的轉義。乙個決策序列就是在變化的狀態中產生出來的,所以,這種多階段最優化決策解決問題的過程就成為動態規劃。

《演算法導論》上面第乙個講解的動態規劃問題就是rod-cutting 問題

input: 有乙個長n公尺的木頭,和乙個price table如下:

長度 i12

3456

**p[i]15

891017

output:找乙個cut的方法,使最後賺的最多

最簡單的方法,遍歷

假設p[i]代表長度為i的木頭的**,max_price代表最大的**, x 代表一次切的公尺數

那麼,如下遞迴肯定成立

def

cut(table, l):

q = 0

if l <= 0:

return

0# i 表示一次切的公尺數

for i in table.keys():

q = max(q, table[i] + cut(table, l - i))

return q

這是乙個簡單的遞迴,但是計算的重複度非常高,計算了大量的重複資料,經過我測試,就算l = 15

這個重複的數字都能讓人做惡夢,重複了92167次

所以這只是乙個暴力遞迴的解法

回過頭來,我們發現,cut(table, l - i)呼叫的次數太多了,我們完全可以建立一張表,來記錄所有的max(q, table[i] + cut(table, l - i)) 這樣,很多值就不用重新計算了,這就是動態規劃的思路

**如下:

def

cut_dp

(table, l):

r = [0] * (l + 1)

for i in range(1, l + 1):

q = 0

for j in table.keys():

q = max(q, table[j] + r[i - j])

r[i] = q

return r[l]

跟非動態規劃的演算法其實比較一致,只不過是計算時,將每次計算的最大值都記錄到了表r中,這樣就大大降低了迭代的次數。

動態規劃(一)

動態規劃的兩種常用形式 1 遞迴型 在函式中呼叫自身 優點 直觀,容易編寫 缺點 可能會因為遞迴層數太深導致爆棧,函式呼叫帶來額外時間開銷。無法使用滾動陣列節省空間。總體來說,比遞推型慢。2 遞推型 for迴圈 效率高,有可能使用滾動陣列節省空間。有的問題只能用遞迴解決,有的問題既可以用遞迴,也可以...

動態規劃 (一)

對於動態規劃的學習總共進行了兩節課,到現在為止還是一頭霧水,雖然看懂了老師上課講的例題,但是做v judge的時候還是都不太會,我主要認為我只知道了動態規劃的基本思想,就是將乙個大的問題,分成若干個小問題,但與貪心演算法不同的是,動態規劃中的每乙個小問題之間都相互影響,在每一步都取得最優解,且在不斷...

動態規劃(一)

題目描述 有n個任務,每個任務有起始時間點,結束時間點,獲得的報酬。同一時間不能同時做兩個任務,問最多可以獲得多少的報酬。解題思路 陣列 pre 儲存每個任務前乙個能做的任務 要做當前任務的情況下 opt 儲存前i個任務的最優解 關鍵思想 為了讓資料更有序,按照每個任務的結束時間以公升序進行排序。每...