求一共有多少種方式系列問題(找零錢)


求一共有多少種方式系列問題(找零錢問題)

背景:

假設有四種面額的錢幣
1 元、2 元、5 元和 10 元,一共給我 10 元
那您可以獎賞我 1 張 10 元,或者 10 張 1 元
或者 5 張 1 元外加 1 張 5 元等等
如果考慮每次獎賞的金額和先后順序 
那么最終 一共有多少種不同的獎賞方式呢?

看到了一個這樣的問題,想用Java代碼解決一下

本方案用到了遞歸的方式計算

下面用Java代碼做了個實現

考慮每次獎賞的金額和先后順序

 public class Allprobability {
    public static void main(String [] args){
        //設置數額
        int a = 10;

        get(a,"");
        System.out.println("over");
    }
    private static int m = 0;

    /**
     * 計算后面可能發生的概率
     * @param num 剩余
     * @param s   緩沖字符串
     */
    private static void get(int num ,String s){
        //0 直接輸出
        if(num == 0) System.out.println("第"+(++m)+"種方法"+s);
        //1
        if(num>=1){
            get(num-1,s+" "+1);
        }
        //2
        if(num>=2){
            get(num-2,s+" "+2);
        }
        //5
        if(num>=5){
            get(num-5,s+" "+5);
        }
        //10
        if(num>=10){
            get(num-10,s+" "+10);
        }
    }
}

以上代碼輸出結果為:

第1種方法 1 1 1 1 1 1 1 1 1 1
第2種方法 1 1 1 1 1 1 1 1 2
第3種方法 1 1 1 1 1 1 1 2 1
......
第127種方法 5 2 2 1
第128種方法 5 5
第129種方法 10
over

真的不做不知道一做嚇一跳啊 才數字10就有這么多結果

考慮重復

我又加了個Info類
這里面存着4種貨幣的數量和一個緩存的num值

import java.util.LinkedList;
import java.util.List;

public class Allprobability2{
    /** 結果 **/
    private static List<Info> infos = new LinkedList<>();
    public static void main(String [] args){
    	//設置數額
        get(new Info(10));
        System.out.println("over");
    }
    private static int m = 0;

    private static void get(Info s){
        int num = s.getNum();
        //0 直接輸出
        if(s.getNum() == 0) {
            if (!s.hasIt())System.out.println("第"+(++m)+"種方法 "+s);
        }
        //1
        if(s.getNum()>=1){
            get(s.cp().add(1).setNum(num-1));
        }
        //2
        if(num>=2){
            get(s.cp().add(2).setNum(num-2));
        }
        //5
        if(num>=5){
            get(s.cp().add(5).setNum(num-5));
        }
        //10
        if(num>=10){
            get(s.cp().add(10).setNum(num-10));
        }
    }


    //將結果封裝為一個結果類
    static class Info{

        public Info(int num){this.num = num;}
        public Info(int a1, int a2, int a5, int a10) {
            this.a1 = a1;
            this.a2 = a2;
            this.a5 = a5;
            this.a10 = a10;
        }

        int num,a1,a2,a5,a10 = 0;

        public boolean hasIt(){
            for (Info i : infos){
                if(i.equals(this))return true;
            }
            infos.add(this);
            return false;
        }

        public int getNum(){return  this.num;}
        public Info setNum(int num){this.num = num;return this;}

        public Info cp(){
            return new Info(this.a1,this.a2,this.a5,this.a10);
        }
        
        public Info add(int a){
            if(a==1)a1++;
            if(a==2)a2++;
            if(a==5)a5++;
            if(a==10)a10++;
            return this;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Info info = (Info) o;

            if(!(this.a1==info.a1))return false;
            if(!(this.a2==info.a2))return false;
            if(!(this.a5==info.a5))return false;
            if(!(this.a10==info.a10))return false;
            return true;
        }

        @Override
        public String toString() {
            return"1元的:"+a1+"個,2元的"+ a2+"個,5元的"+a5+"個,10元的"+a10+"個";
        }
    }


}

這一次輸出結果

第1種方法 1元的:10個,2元的0個,5元的0個,10元的0個
第2種方法 1元的:8個,2元的1個,5元的0個,10元的0個
第3種方法 1元的:6個,2元的2個,5元的0個,10元的0個
第4種方法 1元的:5個,2元的0個,5元的1個,10元的0個
第5種方法 1元的:4個,2元的3個,5元的0個,10元的0個
第6種方法 1元的:3個,2元的1個,5元的1個,10元的0個
第7種方法 1元的:2個,2元的4個,5元的0個,10元的0個
第8種方法 1元的:1個,2元的2個,5元的1個,10元的0個
第9種方法 1元的:0個,2元的5個,5元的0個,10元的0個
第10種方法 1元的:0個,2元的0個,5元的2個,10元的0個
第11種方法 1元的:0個,2元的0個,5元的0個,10元的1個
over

考慮完重復結果 只有11種辦法 相比之前的確實少了不少


免責聲明!

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



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