動態規劃與貪心策略類似,將乙個問題的解決方案視為一系列決策的結果。不同的是,貪心演算法每採用一次貪心選擇便做出乙個不可撤回的決策,而在動態規劃中,還要考察每個最優決策序列中是否包含乙個最優決策自序列。使用動態規劃時,所求問題應具有以下兩種性質。
1.最優子結構性質
所求問題的最優子結構性質是採用動態規劃演算法的條件之一,這種性質又被稱為最優化原理。動態規劃方法採用最優化原理來建立用於計算最優解的遞迴式。所謂最優化原理即不管前面的策略如何,此後的決策必須是基於當前狀態(由上一次決策產生)的最優決策。由於對於有些問題的某些遞迴式來說並不一定能保證最優原則,因此在求解問題時有必要對它進行驗證。若不能保持最優原則,則不可應用動態規劃方法。在得到最優解的遞迴式之後,需要執行回溯以構造最優解。當最優決策序列中包含最優決策子串行時,可建立動態規劃遞迴方程,它可以幫助我們高效地解決問題。
2.子結構重迭性質(重疊子問題)
人們總希望編寫乙個簡單的遞迴程式來求解動態規劃遞迴方程。然而,如果不努力地去避免重複計算,遞迴程式的複雜性將非常可觀。如果在遞迴程式設計中解決了重複計算問題,複雜性將大幅度下降。這種方法的思想是:由程式設定「備忘錄」,每計算出乙個新的子結構的解時,都儲存起來。當遇到一次遞迴時,判斷是否已經計算,如果已經計算,只需取出先前儲存的結果既可。動態規劃遞迴方程也可用迭代方式來求解,這時很自然地避免了重複計算。儘管迭代程式與避免重複計算的遞迴程式有相同的複雜性,但迭代程式不需要附加的遞迴棧空間,因此將比避免重複計算的遞迴程式更快。
動態規劃其實質上是通過開闢記錄表,記錄已求解過的結果,當再次需要求解的時候,可以直接到那個記錄表中去查詢,從而避免重複計算子問題來達到降低時間複雜度的效果。實際上是乙個空間換時間的演算法。動態規劃,通常可以把指數級的複雜度降低到多項式級別。 一般演算法書都會講能不能用動態規劃來求解問題,通常是判斷有沒有最優子結構,通常是通過「剪下技術」來判斷:即證明問題的乙個最優解中,使用的子問題的解本身也必須是最優的。通常是假設乙個子問題不是最優的,那麼找到乙個最優的子問題來替換這個子問題,那麼產生的最優解將優於已找到的那個最優解,從而矛盾。
其實用不用動態規劃來求解問題,還有乙個關鍵是有沒有重複的子問題。這也是使用動態規劃與貪心法的區別所在。貪心法求解的問題也滿足最優解結構,只是它能夠在每一步都能夠「貪婪的」選出當前唯一的最優子問題,並且當前的選擇,是不依賴以前的選擇的,通過這種「貪婪的選擇」選到最後時,就得到了全域性的最優解了,不會產生重複的子問題。而動態規劃,在一步選擇的時候,是通過從以前求出的若干個與本步驟相關的子問題最優解中選擇最好的那個,加上這一步的值,來構造這一步那個子問題的最優解,而如果以前求出的若干個子問題不儲存下來,就需要重新求(通常是遞迴所致)。動態規劃用武之地也無非是儲存這些重複的子問題而避免重新求解而達到高效的目的。 動態規劃的難點在於寫出遞推式。動態規劃的步驟其實是很固定的,而每乙個問題的遞推式如何下手得到會因不同的問題而不同,這是個最關鍵的問題,沒有通用的方法。通常是根據題目的問題,最終要求的 問題,都會有幾個數,以兩個數m,n為例,然後讓求最優值。你就可以使用v[m][n]陣列來儲存最有解,然後把問題替換成i,j兩個數的問題,試圖通過v[i][j]與前面求出來的解建立遞推關係。建立遞推關係後,你可以簡單的寫出遞迴形式的程式,這個程式只需要加上一條if(v[i][j]已求出) return v[i][j];就輕鬆改稱了動態規劃,這就是lookup的形式。當然如果已經有了遞推式,你也很容易寫出從底向上推的迭代形式。 一般的演算法書講的動態規劃都是來求解最優解的問題,或許最初是用來求解規劃問題的,而規劃必然是最優解問題,其實大多數的問題只要存在重複的子問題都可以使用動態規劃的思路,就看你的重複的子問題是不是多的值得使用空間來換時間這個思路了。
附:利用動態規劃求解最優問題的步驟: (1)證明該問題具有最優子結構性質; (2)根據最優子結構性質,寫出最優值的遞迴表示式; (3)根據遞迴式,說明該問題具有重疊子結構性質; (4)採用自底向上的方式計算,寫出求解最優值的非遞迴演算法,同時構造最優解的解空間樹; (5)遍歷解空間樹,求得最優解。
利用貪心演算法求解最優問題的步驟: (1)選定合適的貪心選擇的標準; (2)證明在此標準下該問題具有貪心選擇性質; (3)證明該問題具有最優子結構性質; (4)根據貪心選擇的標準,寫出貪心選擇的演算法,求得最優解。
演算法基本思想之動態規劃
動態規劃 談到演算法最優解 則首先會想到兩個演算法第乙個是貪心演算法,其次才會是動態規劃 再者從問題解決規模的相似程度來看,可能會引出另外的乙個演算法叫做 分治法 更準確的來講叫做分治思想 有乙個問題是 現在假定學校要從計算機工程系選出本年度的三好學生,假定其名額一共有三個,其中學校計算機工程系的學...
動態規劃演算法的基本思想 演算法 動態規劃
演算法 動態規劃 首先學習動態規劃,我們要先知道什麼是動態規劃?演算法導論這本書是這樣介紹這個演算法的,動態規劃與分治方法類似,都是通過組合子問題的解來來求解原問題的。再來了解一下什麼是分治方法,以及這兩者之間的差別,分治方法將問題劃分為互不相交的子問題,遞迴的求解子問題,再將它們的解組合起來,求出...
動態規劃入門(一) DP 基本思想
動態規劃 dp 是一種重要的演算法設計思想,是演算法設計的一柄利器。但是,要掌握dp並且運用自如,絕對不是什麼容易的事。dp的基本思想 1.把乙個大問題的解轉化為若干個小問題的解。2.如果得到了這些小問題的解,然後再經過一定的處理,就可以得到原問題的解。3.這些小問題與原問題有著結構相同,即小問題還...