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

循环方式正向来解:

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;
    }

猜你喜欢

转载自blog.csdn.net/s297165331/article/details/80975280