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