硬币找零

public class CoinChangeDongGui {
    public static void main(String[] args) {         

        //int[] coinValue = new int[] { 25, 21, 10, 5, 1 };  
        int[] coinValue = new int[] { 21, 25, 10, 5 };  
        // 需要找零的面值           
        int money = 63;  
        // 保存每一个面值找零所需的最小硬币数,0号单元舍弃不用,所以要多加1  
        int[] coinsUsed = new int[money + 1];  

        makeChange(coinValue, money, coinsUsed);  
    }

    /**
     * @param coinValue  硬币面值
     * @param money      总钱数
     * @param coinsUsed  索引i表示找零i需要最小的张数.长度比money多1,索引0不要
     */
    private static void makeChange(int[] coinValue, int money, int[] coinsUsed) {
        // TODO Auto-generated method stub
        //先对数组排序
        //Arrays.sort(coinValue);
        coinsUsed[0]=0;  //初始化。找零0当然需要0张
        int M=3000;      //M当成无穷大
        int[][] path=new int[money+1][coinValue.length];//存具体的那几张硬币
        /**
         *       25 21 10 5
         *   0
         *   1
         *   2
         *   3
         *  ...
         *  63 
         */

        for(int cents=1;cents<=money;cents++){//从1,2,3..一直填表到money
            coinsUsed[cents]=M;//如果下边的循环没有找到比cents小的面值,则需要无穷大张
            int dmin=M;
            int t=0;
            for(int k=0;k<coinValue.length;k++){
                if(cents>=coinValue[k]){//如果cents比最接近值大一点
                    int left=cents-coinValue[k];//剩余的面值
                    coinsUsed[cents]=coinsUsed[left]+1;
                }
                if(coinsUsed[cents]<dmin){
                    dmin=coinsUsed[cents];
                    t=k;
                }               
            }
            coinsUsed[cents]=dmin;
            if(coinsUsed[cents]<M){
                for(int i=0;i<coinValue.length;i++){
                    path[cents][i]=path[cents-coinValue[t]][i];
                }           
                path[cents][t]++;               
            }
        }
        for(int i=0;i<=money;i++){
            if(coinsUsed[i]>=M){
                System.out.println("找零"+i+"找不到");
                continue;
            }
            System.out.print("找零"+i+":"+coinsUsed[i]+"张   ");
            for(int j=0;j<coinValue.length;j++){
                System.out.print(coinValue[j]+":"+path[i][j]+" ");
            }
            System.out.println();

        }

    }  
}

//结果:
找零0:021:0 25:0 10:0 5:0 
找零1找不到
找零2找不到
找零3找不到
找零4找不到
找零5:121:0 25:0 10:0 5:1 
找零6找不到
找零7找不到
找零8找不到
找零9找不到
找零10:121:0 25:0 10:1 5:0 
找零11找不到
找零12找不到
找零13找不到
找零14找不到
找零15:221:0 25:0 10:1 5:1 
找零16找不到
找零17找不到
找零18找不到
找零19找不到
找零20:221:0 25:0 10:2 5:0 
找零21:121:1 25:0 10:0 5:0 
找零22找不到
找零23找不到
找零24找不到
找零25:121:0 25:1 10:0 5:0 
找零26:221:1 25:0 10:0 5:1 
找零27找不到
找零28找不到
找零29找不到
找零30:221:0 25:1 10:0 5:1 
找零31:221:1 25:0 10:1 5:0 
找零32找不到
找零33找不到
找零34找不到
找零35:221:0 25:1 10:1 5:0 
找零36:321:1 25:0 10:1 5:1 
找零37找不到
找零38找不到
找零39找不到
找零40:321:0 25:1 10:1 5:1 
找零41:321:1 25:0 10:2 5:0 
找零42:221:2 25:0 10:0 5:0 
找零43找不到
找零44找不到
找零45:321:0 25:1 10:2 5:0 
找零46:221:1 25:1 10:0 5:0 
找零47:321:2 25:0 10:0 5:1 
找零48找不到
找零49找不到
找零50:221:0 25:2 10:0 5:0 
找零51:321:1 25:1 10:0 5:1 
找零52:321:2 25:0 10:1 5:0 
找零53找不到
找零54找不到
找零55:321:0 25:2 10:0 5:1 
找零56:321:1 25:1 10:1 5:0 
找零57:421:2 25:0 10:1 5:1 
找零58找不到
找零59找不到
找零60:321:0 25:2 10:1 5:0 
找零61:421:1 25:1 10:1 5:1 
找零62:421:2 25:0 10:2 5:0 
找零63:321:3 25:0 10:0 5:0 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值