動態規劃是一種在數學和電腦科學中使用的,用於求解包含重疊子問題的最優化問題的方法。其基本思想是,將原問題分解為相似的子問題,在求解的過程中通過子問題的解求出原問題的解。動態規劃的思想是多種演算法的基礎,被廣泛應用於電腦科學和工程領域。比較著名的應用例項有:求解最短路徑問題,揹包問題,專案管理,網路流優化等。
動態規劃在查詢有很多重疊子問題的情況的最優解時有效。它將問題重新組合成子問題。為了避免多次解決這些子問題,它們的結果都逐漸被計算並被儲存,從簡單的問題直到整個問題都被解決。因此,動態規劃儲存遞迴時的結果,因而不會在解決同樣的問題時花費時間。
動態規劃只能應用於有最優子結構的問題。最優子結構的意思是區域性最優解能決定全域性最優解(
對有些問題這個要求並不能完全滿足,故有時需要引入一定的近似)
。簡單地說,問題能夠分解成子問題來解決。
最優子結構性質。如果問題的最優解所包含的子問題的解也是最優的,我們就稱該問題具有最優子結構性質(即滿足最優化原理)。最優子結構性質為動態規劃演算法解決問題提供了重要線索。
子問題重疊性質。子問題重疊性質是指在用遞迴演算法自頂向下對問題進行求解時,每次產生的子問題並不總是新問題,有些子問題會被重複計算多次。動態規劃演算法正是利用了這種子問題的重疊性質,對每乙個子問題只計算一次,然後將其計算結果儲存在乙個**中,當再次需要計算已經計算過的子問題時,只是在**中簡單地檢視一下結果,從而獲得較高的效率。
計算斐波那契數列的乙個最基礎的演算法是,直接按照定義計算:
function fib(n)
if n = 0 or n = 1
return 1
return fib(n − 1) + fib(n − 2)
當n=5
時,fib(5)
的計算過程如下:
fib(5)
fib(4) + fib(3)
(fib(3) + fib(2)) + (fib(2) + fib(1))
((fib(2) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1))
(((fib(1) + fib(0)) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1))
由上面可以看出,這種演算法對於相似的子問題進行了重複的計算,因此不是一種高效的演算法。實際上,該演算法的運算時間是指數級增長的。改進的方法是,我們可以通過儲存已經算出的子問題的解來避免重複計算:
array map [0...n] =
fib( n )
if ( map( n ) is cached )
return map( n )
return map( n ) = fib( n - 1 ) + fib( n - 2 )
將前n個已經算出的前n
個數儲存在陣列map
中,這樣在後面的計算中可以直接易用前面的結果,從而避免了重複計算。演算法的運算時間變為o(n)。
動態規劃 什麼是動態規劃?
先來看看 資訊學奧賽一本通第5版 是怎麼說的 動態規劃程式設計是對解最優化問題的一種途徑 一種方法,而不是一種特殊演算法。不像前面所述的那些搜尋或數值計算那樣,具有乙個標準的數學表示式和明確清晰的解題方法。動態規劃程式設計往往是針對一種最優化問題,由於各種問題的性質不同,確定最優解的條件也互不相同,...
mysql動態規劃 動態規劃
動態規劃 能夠動態規劃的問題具有以下特點 可分解成規模更小的子問題 子問題的結果可復用 關鍵是要理解狀態轉移方程的含義就好啦!數字三角形 問題描述 在數字三角形尋找從頂到底的路徑,使得路徑經過的數字之和最大。規定每一步只能往左下或右下走,求出最大路徑和。遞迴解法 include include us...
使用What的表達
使用 what 的表達 請使用 what 疑問句詢問大致發生的情況。這些表達是常用的問候方式。what s up?怎麼了?what s going on?發生什麼事了?如果您沒有具體要談的事情,這些表達的一般回答可能是 not much.what s up with you?還行。您怎麼樣?i do...