算法:动态规划-硬币找钱问题:最少需要多少硬币来找钱,并且分别是多少硬币

循环方式正向来解:

public static void main(String[] args) {
        /**
         * 拥有的硬币数额
         */
        int[] coinValue = new int[] { 25, 21, 10, 5, 1 };
        /**
         * 要破开的数额
         */
        int money = 63;
        /**
         * 存储已经有的钱数最优解 0位置存储需要的硬币数目
         */
        int[][] coinsUsed = new int[money + 1][coinValue.length+1];
        /**
         * 计算
         */
        makeChange(coinValue, coinValue.length, money, coinsUsed);
    }




    private static void makeChange(int[] coinValue, int length, int money, int[][] coinsUsed) {
        /**
         * 0元的最优解就是0
         */
        coinsUsed[0][0] = 0;
        /**
         * 从1开始计算最优解
         */
        for(int i=1;i<=money;i++){
            /**
             * 用1元来计算多少个硬币
             */
            coinsUsed[i][0] = i;
            for(int j = 0;j<coinValue.length;j++){
                int c = coinValue[j];
                if(c<=i){
                    /**
                     * 1是表示当前的硬币,coinsUsed[i-c]是之前的最优解
                     */
                    int temp = i-c;
                    int min = coinsUsed[temp][0]+1;
                    if(min<=coinsUsed[i][0]){
                        coinsUsed[i][0]= min;
                        for(int m=0;m<coinValue.length;m++){
                            if(m==j){
                                coinsUsed[i][m+1] = coinsUsed[temp][m+1]+1;
                            }else {
                                coinsUsed[i][m+1] = coinsUsed[temp][m+1];
                            }
                        }
                    }
                }
            }
            System.out.println("面值为 " + (i) + " 的最小硬币数 : " + coinsUsed[i][0]+ " 25 元面值 : " + coinsUsed[i][1]+ " 21 元面值: " + coinsUsed[i][2]+ " 10 元面值: " + coinsUsed[i][3]+ " 5 元面值: " + coinsUsed[i][4]+ " 1 元面值: " + coinsUsed[i][5]);
        }


    }

迭代方式逆向来解:

private static int[] coinValue;
    private static int[][] coinsUsed ;

    public static void main(String[] args) {
        /**
         * 拥有的硬币数额
         */
        coinValue = new int[] { 25, 21, 10, 5, 1 };
        /**
         * 要破开的数额
         */
        int money = 63;
        /**
         * 存储已经有的钱数最优解 0位置存储需要的硬币数目
         */
        coinsUsed = new int[money + 1][coinValue.length+1];
        /**
         * 计算
         */
       // makeChange(coinValue, coinValue.length, money, coinsUsed);

        getYouJie(money);
    }


    private static void makeChange(int[] coinValue, int length, int money, int[][] coinsUsed) {


    }

    private static int[] getYouJie(int money){
        if(money==1){
            int md = 1;
        }
        if(money==0){
            return coinsUsed[0];
        }
        if(coinsUsed[money][0]!=0){
            return coinsUsed[money];
        }
        int[] min = coinsUsed[money];
        min[0] = money;
        for(int i=0;i<coinValue.length;i++){
            if(money>=coinValue[i]){
                int[] coin =  getYouJie(money-coinValue[i]);
                /**
                 * 之前的硬币数目加1
                 */
                int m = coin[0]+1;
                if(m<=min[0]){
                    min[0] = m;
                    for(int k=1;k<min.length;k++){
                        if(k-1==i){
                            min[k] = coin[k]+1;
                        }else {
                            min[k] = coin[k];
                        }
                    }
                }
            }
        }
        System.out.println("面值为 " + (money) + " 的最小硬币数 : " + coinsUsed[money][0]+ " 25 元面值 : " + coinsUsed[money][1]+ " 21 元面值: " + coinsUsed[money][2]+ " 10 元面值: " + coinsUsed[money][3]+ " 5 元面值: " + coinsUsed[money][4]+ " 1 元面值: " + coinsUsed[money][5]);
        return min;
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二蛋和他的大花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值