1. 程式人生 > >動態規劃-最少硬幣問題

動態規劃-最少硬幣問題

題目描述

如果我們有面值為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.