第四届程序设计大赛 苹果
Time Limit:1000MS Memory Limit:65536K
Total Submit:90 Accepted:48
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
分析转自:http://uzone.univs.cn/blog_2984978_mgf8x9eow0qnb2wreow1.html
分析:放法要分盘子全放满了和没放满的情况。
由于当(1):苹果数少于盘子数时,此时把盘子减少一个,对结果没影响。(为什么?试想如果10个苹果放1000个盘子,是不是很多盘子没用呢?嘿嘿)这样此时
fun(m,n)=fun(m,n-1);
(2):苹果数少于盘子数,此时仍可以分成两种情况:放满和没有放满。
没放满:fun(m,n)转化成fun(m,n-1)(因为你有盘子没用)
放满:放满即为每个盘子都有苹果,那么我把每个盘子的苹果拿一个出来结果仍然会是一样。此时的fun(m,n)转化成fun(m-n,m);(既然每个盘子必须有个苹果,那么这些苹果的存在与否可以当作不影响结果,比如拿5个苹果放2个盘子,又要满足每个盘子必须有个苹果的话那肯定有两个苹果不能动,必须放在盘子下,然后他们就与盘子融为一体,我们就当作看不见他们了。。。。。嘿嘿);
好了,函数进来盘子与苹果的数量关系每次都满足上面的两种情况,每次又归化成更简单的继续下去,那么很显然就想到了递归。
代码如下:
#include
int fun(int m,int n)
{
if(m<=1||n==1)
return 1;//为m可能为和n相等,此时如果要满足每个盘子都有的话只有一种放法。只有一个盘子也只有一种
if(n==0)
return 0;
if(n>m)//至少有一个盘子为空
return fun(m,n-1);
else//至少一个盘子为空 + 所有盘子都不为空
return fun(m,n-1)+fun(m-n,n);
}
int main()
{
printf("%d\n",fun(7,3));
}
My code:
#include
int fun(int m,int n)
{
if(m<=1||n==1)
return 1;//为m可能为和n相等,此时如果要满足每个盘子都有的话只有一种放法。只有一个盘子也只有一种
if(n==0)
return 0;
if(n>m)//至少有一个盘子为空
return fun(m,n-1);
else//至少一个盘子为空 + 所有盘子都不为空
return fun(m,n-1)+fun(m-n,n);
}
int main()
{
int m,t,n;
while(scanf("%d",&t)==1)
{
while(t--)
{
scanf("%d%d",&m,&n);
printf("%d\n",fun(m,n));
}
}
return 0;
}