前言
一、案例描述
二、問題分析
三、**示例
總結動態規劃是一種演算法技巧,先舉乙個例子:
如何讓乙個四歲的小孩理解動態規劃的思路?國外友人有這樣乙個例子:列出乙個1+1+1+1+1+1+1+1=?的式子,讓小孩回答,小孩思索數秒後會告訴你答案是8。隨後在前面再多寫乙個+1,再提問答案是多少,小孩會瞬間告訴你是9,問小孩為什麼這麼快就能得到答案,他會告訴你,因為只需要再加乙個1就可以了。
這裡面就包含了動態規劃的思想:將待求解的問題分成若干個子問題,從子問題的求解得到原問題的解,而在這個過程中,已經求解過的子問題,其解是已經被記錄下的,這樣就能避免很多重複的計算。下面我們看乙個具體的簡單案例。
乙個小偷準備挨家挨戶進行偷竊,每一家都有一些能偷到的金額值,但是不能連續進入相鄰的兩間房屋,否則會被發現。將這個設定抽象成乙個陣列,每家擁有的金額組成乙個非負的整型陣列,在不被發現的情況下,計算小偷能偷到的最大數額。
例如[1,2,5,3,4,8,2],那麼最大值就是:第一家(1)+第三家(5)+第六家(8)=14.
先來分析一些特殊情況:
①.假如只有一間房屋,那麼小偷只能偷竊該房間,那麼最大值就是該房間裡的金額值。
②.假如有兩間房屋,那麼兩間房屋裡,哪間房屋的金額值高,其值就是小偷能偷到的最大值。
那麼,當房間數量大於2時,由於小偷不能進入相鄰的房間:
①.假如小偷進入了第x間房,則他必然沒有進入x-1間房,最高金額sum就等於前面x-2間房中的最大總金額值加上第x間房裡的金額值。
②.假如小偷沒有進入第x間房,那麼最高金額sum就等於前面x-1間房裡的最高總金額。
於是,x任取的情況下,小偷進入第x間房屋和沒有進入第x間房屋這兩種情景就涵蓋了這個案例的題解。
即最高金額總值,就是這兩種情況中的更大的那個值。用 sum[i] 來表示前 i 間房屋裡能偷到的最大金額值,用cash [i]來表示第 i 間房裡的金額,根據上面的分析可以得到下面的關係式(狀態轉移方程):
sum[i] = max(sum[i-2]+cash[i] , sum[i-1])
再把前面分析的特殊情況作為邊界條件考慮進去:
①. sum[0] = cash[0] ---------------------------房間數為1時
②. sum[1] = max(cash[0] ,cash [1]) ------ 房間數為2時
這樣,假設有n間房屋,那麼最後總值陣列中的最大值就是 sum[n-1] .
將上述的思路轉化為**如下:
public
static
introb
(int
cash)
//一間房屋的情況,該房間內的金額就是最大值,直接返回該值
if(cash.length ==1)
//建立乙個用於儲存最大總和值的陣列 sum
int len = cash.length;
int[
] sum =
newint
[len]
;//給定sum的邊界條件,房間數為1和2時
sum[0]
= cash[0]
; sum[1]
= math.
max(cash[0]
, cash[1]
);//從房間數為3開始,最大總值陣列的每乙個元素值應該滿足以下的狀態轉移方程
for(
int i =
2; i < len; i++
)//遍歷完陣列,也就找到了最大值.
return sum[sum.length -1]
;}
測試上述方法,比如就將我們前面列舉的陣列[1,2,5,3,4,8,2]代入方法裡。
public
static
void
main
(string[
] args)
;int x =
rob(cash)
; system.out.
println
("小偷能偷到的最大金額為:"
+x);
}
執行結果如下:
這就是乙個簡單的案例,解題方法體現了動態規劃的思想。動態規劃演算法通常用於求解具有某種最優性質的問題。在這類問題中,可能會有許多可行解。每乙個解都對應於乙個值,我們希望找到具有最優值的解。這時候將問題分成很多子問題,並且求出子問題的解,用乙個容器(本例中的陣列)來記錄所有已解的子問題的答案。不管該子問題以後是否被用到,只要它被計算過,就將其結果記錄在容器中,避免重複計算,這就是動態規劃法的基本思路。
乙個簡單的動態規劃題
一直感覺 動態 規劃和排列好難的 乙個簡單的題目。開司,乙個整日遊手好閒 無所事事 混跡人生 軟弱無能 放縱慾望 毫無進取 嗯,實在是太多了,就不一一枚舉了。總之,他就是完美的符合了我們日常中對人渣這一詞的認識。不過他有這唯一,也是無敵般的特長,就是逆境求生 不論是什麼樣的逆境,他都可以翻盤。這不是...
動態規劃 乙個簡單爬梯子問題
問題描述 乙個樓梯有20級,每次走1級或兩級,請問從底走到頂一共有多少種走法?分析 假設從底走到第n級的走法有f n 種,走到第 級有兩個方法,乙個是從 n 1 級走一步,另乙個是從第 級走兩步,前者有f n 1 種方法,後者有f n 2 種方法,所以有f n f n 1 f n 2 還有f 0 1...
C 處理乙個動態規劃的問題
要求是遞迴,動態規劃,想了想這種方法也是最簡單的 所謂動態規劃 把多階段過程轉化為一系列單階段問題,利用各階段之間的關係,逐個求解。動態規劃演算法通常用於求解具有某種最優性質的問題。在這類問題中,可能會有許多可行解。每乙個解都對應於乙個值,我們希望找到具有最優值的解。動態規劃演算法與分治法類似,其基...