假設有四種面額的錢幣 1 元、2 元、5 元和 10 元,一共給我 10 元 那您能夠獎賞我 1 張 10 元,或者 10 張 1 元 或者 5 張 1 元外加 1 張 5 元等等 若是考慮每次獎賞的金額和前後順序 那麼最終 一共有多少種不一樣的獎賞方式呢?
看到了一個這樣的問題,想用Java代碼解決一下java
本方案用到了遞歸的方式計算緩存
下面用Java代碼作了個實現ide
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); } } }
以上代碼輸出結果爲:this
第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就有這麼多結果code
我又加了個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種辦法 相比以前的確實少了很多get