M個蘋果分給N個人,每個人至少一個,有多少種分法?


問題:M個蘋果分給N個人,沒人最少分一個,共有多少種分法?輸出所有的分法

例如:6個蘋果分給三個人,有“2, 2, 2”,“1, 2, 3”,“1, 1, 4”,三種分法,像“1, 2, 3”,“3, 2, 1”,“2, 3, 1”均屬於同一種分法

解決這個問題的思路可以用動態規划的思想,我們最終要獲得的應該是一個二維數組List<List>的結構,里面的每個數組即表示一種分法。

我們可以利用動態規划的思想,假設f(n,m)表示m個蘋果分給n個人所有的分法,那f(n,m)和f(n,m-1)的關系可以理解為:在f(n,m-1)得到的所有分法基礎上,現在多出來了一個蘋果,多出來的蘋果可以分給n中的任意一個人,比如f(n,m-1)的結果集里有一種分法為“x,y,z”,那么f(n,m)就是在這個分法之上,多出了三種“x+1,y,z”,“x,y+1,z”,“x,y,z+1”的分法。而當n=m時,則返回一個[[1,1,1。。。]]的數組,里面的數組長度為n,表示所有人一人一個。

 1 private static List<int[]> getAllWays(int n, int m){
 2         List<int[]> result = new ArrayList<>();
 3         if (n == m){
 4             int[] ints = new int[n];
 5             for (int i = 0; i < ints.length; i++) {
 6                 ints[i] = 1;
 7             }
 8             result.add(ints);
 9             return result;
10         }
11 
12         List<int[]> ways = getAllWays(n, m-1);
13         for (int[] way : ways) {
14             for (int i = 0; i < way.length; i++) {
15                 int[] newway = way.clone();
16                 newway[i] = way[i] + 1;
17                 Arrays.sort(newway);//這里排序是為了不考慮順序
18                 if (!isExist(newway,result)){//排除相同分法
19                     result.add(newway);
20                 }
21             }
22         }
23         return result;
24     }
25 
26     private static boolean isExist(int[] array,List<int[]> list){
27         boolean isExist = false;
28         for (int[] ints : list) {
29             if (array.length != ints.length) continue;
30             int front = 0;
31             while (front < array.length){
32                 if (array[front] != ints[front]) break;
33                 front++;
34             }
35             if (front == ints.length){
36              isExist = true;
37              break;
38             }
39         }
40         return isExist;
41     }

 調用這個函數就可以獲得所有分法


免責聲明!

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



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