動態規劃演算法通常基於乙個遞推公式以及乙個或多個初始狀態,當前子問題的解由上一次子問題的解推出。
在動態規劃演算法中有乙個經典的例子就是硬幣找零問題。
如果我們有面值為1元、3元、5元的硬幣若干,如何用最少的硬幣湊夠11元?
基於動態規劃的思想,我們可以從1元開始計算最少需要幾個硬幣,然後再求2元、3元、4元...
首先,當i=0時,我們需要0個,即d(0)=0;
當i=1時,只有面值為1元的硬幣可用,d(1)=d(1-1)+1=1;
當i=2時,仍然只有面值為1元的硬幣可用,d(2)=d(2-1)+1=2;
當i=3時,可用的硬幣有1元和3元,如果我拿了1元的,我的目標就變成了湊夠3-1=2元需要的最少硬幣了,即d(3)=d(3-1)+1=3,另乙個方案是我拿了乙個3元的硬幣,目標就是湊夠3-3=0元需要的最少硬幣數量,即d(3)=d(3-3)+1=1,所以綜合兩者方案的最小值d(3)=min=1;
當i=4時,可用的硬幣有1元和3元,如果我拿了1元的,我的目標就變成了湊夠4-1=3元需要的最少硬幣了,即d(4)=d(4-1)+1=2,另乙個方案是我拿了乙個3元的硬幣,目標就是湊夠4-3=1元需要的最少硬幣數量,即d(4)=d(4-3)+1=2,所以綜合兩者方案的最小值d(3)=min=2;
d(5)=1;
d(6)=2;
d(7)=3;
d(8)=2;
d(9)=3;
d(10)=2;
由上面可以退出公式,d(i)=min,其中i-vj>=0,vj表示第j個硬幣的面值。
現在,我們回到原題中,d(11)=min,其中vj可以取值為1,3,5。當vj=1時,d(11)=d(10)+1=3,當vj=3時,d(11)=d(8)+1=3,當vj=5時,d(11)=d(6)+1=3,所示d(11)=3。
首先定義以下變數:
values : 儲存每一種硬幣的幣值的陣列
valuekinds :幣值不同的硬幣種類數量,即values陣列的大小
money : 需要找零的面值
coinsused : 儲存面值為 i 的紙幣找零所需的最小硬幣數
當求解總面值為 i 的找零最少硬幣數 coinsused[ i ] 時,將其分解成求解 coinsused[ i – cents]和乙個面值為 cents 元的硬幣,由於 i – cents < i , 其解 coinsused[ i – cents] 已經存在,如果面值為 cents 的硬幣滿足題意,那麼最終解 coinsused[ i ] 則等於 coinsused[ i – cents] 再加上 1(即面值為 cents)的這乙個硬幣。**如下:
publicclass
coinschange
} }
//儲存最小硬幣數
coinsused[cents] =mincoins;
} system.out.println("面值為 " + (money) + " 的最小硬幣數 : " + coinsused[cents-1]);
} public
static
void
main(string args)
; //需要找零的面值
int money = 11;
//儲存每乙個面值找零所需的最小硬幣數,0號單元捨棄不用,所以要多加1
int coinsused = new
int[money + 1];
makechange(coinvalue, coinvalue.length, money, coinsused);
}}
動態規劃演算法
一 動態規劃演算法原理 將待求解的問題分解成若干個相互聯絡的子問題,先求解子問題,然後從這些子問題的解得到原問題的解 對於重複出現的子問題,只在第一次遇到的時候對它進行求解,並把答案儲存起來。了不去求解相同的子問題,引入乙個陣列,把所有子問題的解存於該陣列中,這就是動態規劃所採用的基本方法。動態規劃...
動態規劃演算法
動態規劃 通過把原問題分解為相對簡單的子問題來求解複雜問題。動態規劃常常適用於有重疊子問題和最優子結構性質的問題。演算法總體思想 演算法的基本步驟 演算法的基本要素 最優子結構 重疊子問題 備忘錄方法 問題描述 子串行 公共子串行 最長公共子串行 lcs 問題 問題分析 動態規劃求解lcs問題 最長...
動態規劃演算法
動態規劃演算法的思路 動態規劃法即 dynamic programming method dp 是系統分析中的種常用方法。動態規劃法是20世紀50年代由貝爾曼 r.bellman 等人提出的,用來解決多階段決策過程問題的一種最優化方法。多階段決策過程是指把研究問題分成若干個相互聯絡的階段,由每個階段...