Description
把M个同样的鸡蛋放在N个同样的篮子里,允许有的篮子空着不放,问共有多少种不同的放法?
5,1,1和1,5,1是同一种分法。
Input
第一行是测试数据的数目t(0 <= t <= 20)。
以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
Output
Sample Input
Sample Output
#include<iostream>
using namespace std;
//传进鸡蛋的数量与篮子的数量返回放置鸡蛋方法的种数
int find_num_of_ways(int num_of_eggs, int num_of_baskets);
int main(){
int t;
cin >> t;
while (t--){
int num_of_eggs, num_of_baskets;
cin >> num_of_eggs >> num_of_baskets;
cout << find_num_of_ways(num_of_eggs, num_of_baskets) << endl;
}
return 0;
}
int find_num_of_ways(int num_of_eggs, int num_of_baskets) {
//只有1个篮子或1个鸡蛋时只有1种放置方法
if (num_of_baskets == 1 || num_of_eggs == 1)
return 1;
//篮子多余鸡蛋时等于每个篮子放一个鸡蛋的情况(1种)加上把鸡蛋放到比鸡蛋数量少1个篮子的情况数
if (num_of_baskets >= num_of_eggs)
return 1 + find_num_of_ways(num_of_eggs, num_of_eggs - 1);
else
//每个篮子放一个鸡蛋后剩下num_of_eggs-num_of_baskets个鸡蛋放到num_of_baskets个篮子里
return find_num_of_ways(num_of_eggs - num_of_baskets, num_of_baskets)
//不是全部篮子用上的情况
+ find_num_of_ways(num_of_eggs, num_of_baskets - 1);
}
-----------------------------------------------------------------------------------------------------------
以上是求出了放鸡蛋情况的总数。那么怎样求出所有的具体情况呢?
可以参考整数划分的解法。整数划分实际上是将n个鸡蛋放入n个篮子中。
稍加修改就可以应用到这题里面。
#include<stdio.h>
#pragma warning(disable:4996)
int list[255];
void split(int n, int m, int max){
int i;
// 如果分割完毕
if (n == 0){
// 遍历输出数组
for (i = 0; i < m; i++){
printf("%d", list[i]);
}
for (; i < max; i++){ // 空“篮子”补上0
printf("0");
}
printf("\n");
return;
}
// 由大到小进行分割
for (i = n; i >= 1; i--){
// 如果未分割或当前分割的数字不大于上一个分割的数字
if (m == 0 || i <= list[m - 1]){
// 将分割的数字存入数组
list[m] = i;
// 如果m小于总的“篮子”数(m从0开始计数),则分割剩下的数字
if (m < max) {
split(n - i, m + 1, max);
}
}
}
}
int main() {
int T, n, max;
scanf("%d", &T); //
while (T--) {
scanf("%d%d", &n, &max); // 输入鸡蛋个数和篮子个数
split(n, 0, max);
}
return 0;
}