畢業后就怎么學過算法,還在上學的時候學過數據結構,現在基本上都還給老師了,可惜老師學費沒有還給我。。。
情景: 類似於給定一個數字,算他由多少個數字組成,比如:36 現在有10、5、1 ,那么最佳帥3個10,1個5,1個1組成(默認優先取最大)。因為我們這邊業務上面需要開發票,有的時候不想一個一個算,就讓我們寫一個。但是他發票的個數不是固定的、無盡的,所以每次就要判斷下,如果:36 現在基數還是10、5、1 但是 只讓你拿1個10、2個5、若干個1,那么組合應該是:1個10,2個5,16個1,大概就是這個意思。
添加兩個list,一個存放基數(從大到小)另外一個存放基數的對應個數。
List list = new ArrayList(); list.add(10); list.add(100); list.add(1); list.add(20); list.add(50); list.add(5); Collections.sort(list, Collections.reverseOrder()); List list2 = new ArrayList(); list2.add(1); //100對應個數(下同) list2.add(4); //50 list2.add(1); //20 list2.add(20); //10 list2.add(50); //5 list2.add(1000); //1
下面就是遞歸了。。沒有啥難度。。參數分別是: 輸入的總數,集合的初始下標,基數集合,基數個數集合
public void c(int totle, int flag, List list, List list2) { //System.out.println("當前總額" + totle + ",當前額度" + list.get(flag)); int sum = 0; for (int i = 0; i < list.size(); i++) { sum += (int) list.get(i) * (int) list2.get(i); } if (sum < totle) { System.out.println("發票總額不夠,請添加發票!!!!"); } else { if (totle % (int) list.get(flag) == 0) { int s = totle / (int) list.get(flag); //System.out.println(s + ""); if (s > (int) list2.get(flag)) { System.out.println("需要" + list.get(flag) + "元的發票" + s + "張,目前只有" + list2.get(flag) + "張,全部使用!"); totle -= (int) list2.get(flag) * (int) list.get(flag); System.out.println(totle); c(totle, ++flag, list, list2); } else { System.out.println("需要" + list.get(flag) + "元的發票" + s + "張"); } } else { int s = totle / (int) list.get(flag); if (s > (int) list2.get(flag)) { System.out.println("需要" + list.get(flag) + "元的發票" + s + "張,目前只有" + list2.get(flag) + "張,全部使用!"); totle -= (int) list2.get(flag) * (int) list.get(flag); System.out.println(totle); c(totle, ++flag, list, list2); } else { totle = totle % (int) list.get(flag); System.out.println("需要" + list.get(flag) + "元的發票" + s + "張"); System.out.println(totle); c(totle, ++flag, list, list2); } } } }
假設:
c(365, 0, list, list2);
輸出
如果輸入超過所有的總額,那么如下:
很簡單,記錄一下,也是提醒下自己,算法也是蠻重要的。。。沒事也要跟着慢慢研究!!!