算法筆記_048:找零問題(Java)


目錄

1 問題描述

2 解決方案

2.1 動態規划法

 


1 問題描述

現需找零金額為n,則最少需要用多少面值為d1 < d2 < d3 < ... < dm的硬幣?(PS:假設這m種面值d1 < d2 < d3 < ... < dm的硬幣,其中d1 = 1,且每種硬幣數量無限可得)

 


2 解決方案

2.1 動態規划法

本文編碼思想參考自《算法設計與分析基礎》第三版,具體講解如下:

 

 

具體代碼如下:

package com.liuzhen.chapter8;

public class ChangeMaking {
    
    public void getChangeMakingN(int[] coinType,int n){
        int[] minNumber = new int[n+1];   //初始化后,所有元素均為0,其中minNumber[0] = 0,表示無須找零
        int[] tempMinJ = new int[n+1];    //tempMinJ[0]在此處無含義
        for(int i = 1;i <= n;i++){
            int j = 0;
            int tempJ = -1;      //用於h獲取minNumber[i]最小值中當前新使用的硬幣面值數組下標
            int temp = Integer.MAX_VALUE;        //計算當前minNumber[i]最小值,初始化int類型最大值
            while(j < coinType.length && i >= coinType[j]){
                if(minNumber[i-coinType[j]] + 1 < temp){
                    temp = minNumber[i-coinType[j]] + 1;
                    tempJ = j;
                }
                j++;
            }
            minNumber[i] = temp;
            tempMinJ[i] = tempJ;
        }
        
        System.out.println("給定硬幣面值種類依次為:");
        for(int i = 0;i < coinType.length;i++)
            System.out.print(coinType[i]+" ");
        
        System.out.println("\n找零大小從1到"+n+"的最少硬幣組合數目為:");
        for(int i = 1;i < minNumber.length;i++)
            System.out.print(minNumber[i]+" ");
        
        System.out.println("\n對應找零大小從1到"+n+"新增的硬幣數組下標為:");
        for(int i = 1;i < tempMinJ.length;i++)
            System.out.print(tempMinJ[i]+" ");
        
        System.out.println("\n對應找零大小從1到"+n+"新增的硬幣數組下標對應的硬幣面值為:");
        for(int i = 1;i < tempMinJ.length;i++)
            System.out.print(coinType[tempMinJ[i]]+" ");
        
        System.out.println("\n\n找零大小為"+n+"的硬幣組合最少數目為:"+minNumber[minNumber.length-1]);
        System.out.print("找零大小為"+n+"的硬幣組合最少數目對應的硬幣面值依次為:");
        int needN = n;
        int minJ = tempMinJ.length-1;
        while(needN > 0){
            System.out.print(coinType[tempMinJ[minJ]]+" ");
            needN = needN - coinType[tempMinJ[minJ]];
            minJ = needN;
        }
    }
    
    public static void main(String[] args){
        ChangeMaking test = new ChangeMaking();
        int[] coinType = {1,3,4};
        test.getChangeMakingN(coinType, 6);
    }
}

運行結果:

給定硬幣面值種類依次為:
1 3 4 
找零大小從1到6的最少硬幣組合數目為:
1 2 1 1 2 2 
對應找零大小從1到6新增的硬幣數組下標為:
0 0 1 2 0 1 
對應找零大小從1到6新增的硬幣數組下標對應的硬幣面值為:
1 1 3 4 1 3 

找零大小為6的硬幣組合最少數目為:2
找零大小為6的硬幣組合最少數目對應的硬幣面值依次為:3 3 

 

 

參考資料:

   1.算法設計與分析基礎(第3版)  Anany Levitin 著 潘彥 譯

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM