Description
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
Input
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
Output
对输入的每组数据M和N,用一行输出相应的K。
Sample Input
1
7 3
Sample Output
8
借鉴别人的思想用递归做的,解释在代码里
#include<iostream>
#include<algorithm>
using namespace std;
//用递归做,也可以用动态规划
/*
从一个盘子开始分(每个盘子都要分到),每次处理以后就增加一个盘子,所以包含了空盘子情况
m<n 苹果数比盘子数还少,正好分完的情况也就是一种
m=n 正好分完的情况也是一种
m>n 苹果数比盘子数还多,那么当你分完一个盘子以后,下一次要分的就是把剩下的苹果
分到剩下的盘子里
临界条件就是最后你分到苹果比盘子还少或者相等,那么只有一种分法
*/
int f(int m, int x)
{
int ans = 0;
//把m个苹果分成x份,
if (m < x)//苹果是不能切开的,这也保证不会有,当有很多空盘子时再增加一个空盘会使结果不正确
return 0;
else if (m == x)//这种情况下恰好分完就之后一种情况
return 1;
else
{
if (x == 1)
return 1;//第一次忘记了这个条件,分成一份的时候就一种情况
for (int i = 1; i <= x; i++)//第二次判断条件出错,m>x了已经,所以直接用x
{
ans += f(m - x, i);
}
}
return ans;
}
int main()
{
int k, m, n;
cin >> k;
for (int i = 0; i < k; i++)
{
int ans = 0;//第二次发现每次初始化应该在里边
cin >> m >> n;
for (int i = 1; i <= min(m,n); i++)
{
ans += f(m, i);//分成i份,这里剩下的没有用的盘子就是空盘子
}
cout << ans << endl;
}
system("pause");
return 0;
}