動態規劃-最少硬幣問題
阿新 • • 發佈:2019-02-06
題目描述
如果我們有面值為1元、3元和5元的硬幣若干枚,如何用最少的硬幣湊夠11元?
分析
來手寫一下求取最小個數的過程,用MIN[i]表示要湊得i元所需的最少硬幣個數
MIN[0] = 0
MIN[1] = min{MIN[1-1]+1} = 1
MIN[2] = min{MIN[2-1]+1} = 2
MIN[3] = min{MIN[3-1]+1,MIN[3-3]+1} = min{3,1} = 1
MIN[4] = min{MIN[4-1]+1,MIN[4-3]+1} = min{2,2} = 2
MIN[5] = min{MIN[5-1]+1,MIN[5-3]+1 ,MIN[5-5]+1} = min{3,3,1} = 1
MIN[6] = min{MIN[6-1]+1,MIN[6-3]+1,MIN[6-5]+1} = min{2,2,2} = 2
MIN[7] = min{MIN[7-1]+1,MIN[7-3]+1,MIN[7-5]+1} = min{3,3,3} = 3
MIN[8] = min{MIN[8-1]+1,MIN[8-3]+1,MIN[8-5]+1} = min{4,2,2} = 2
MIN[9] = min{MIN[9-1]+1,MIN[9-3]+1,MIN[9-5]+1} = min{3,3,3} = 3
MIN[10] = min{MIN [10-1]+1,MIN[10-3]+1,MIN[10-5]+1} = min{4,7,2} = 2
MIN[11] = min{MIN[11-1]+1,MIN[11-3]+1,MIN[11-5]+1} = min{3,3,3} = 3
我們求解的問題也就是求MIN[11]的值,MIN[i]就是這個問題的狀態,可以得到狀態轉移方程為:MIN[i] = min{MIN[i-Vj]+1},其中i表示要湊i枚硬幣,Vj表示第j枚硬幣的面值,在這裡Vj分別為1,3,5,且0<=i-Vj
Java程式碼實現
public class MinCoins {
public static void main(String[] args) {
int[] a = new int[]{1,3,5};
minCoins(a,11);
}
public static void minCoins(int[] a,int x) {
int[] MIN = new int[x+1];
MIN[0] = 0;
for (int i = 0 ; i < MIN.length; i++) {
//每次迴圈首先都要將MIN[i]設值i,也就置為最大值。
MIN[i] = i;
for (int j = 0;j<a.length;j++) {
//接著要判斷這次要湊的硬幣是否大於最基本的三枚硬幣的面值{1,3,5},並且去除某個面值之後的硬幣個數加1的總個數要小於剛剛設定的最大值
if (i>=a[j] && (MIN[i-a[j]]+1)<MIN[i]) {
//要儲存此次得到的最小值
MIN[i] = MIN[i-a[j]]+1;
System.out.println("Temp --> MIN["+i+"] = "+MIN[i]);
}
}
System.out.println("MIN["+i+"] = "+MIN[i]);
}
}
}
THE END.