【题目描述】
有一天,皮皮扬有钱了,就叫上了CC去吃一个榴芒,到了店里的时候,皮皮扬买了n个芒果班戟,她想把这些芒果班戟放在m个盘子里,允许盘子可以不放,不过皮皮扬的思维不好,不知道怎么放这些,现在就需要我们来帮皮皮扬算一下一共有多少种不同的分法?
【输入】
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数n和m,以空格分开。1<=n,m<=10。
【输出】
对输入的每组数据n和m,用一行输出相应的k。
样例输入
1
7 3
样例输出
8
提示
5,1,1和1,5,1 是同一种分法。
解题思路
写一个函数fun(int n,int m)
将n个芒果放在m个盘子上,可以这样拆开:
将n-m个芒果放在m个盘子上(代表每一个盘子都有芒果的情况);
将n个芒果放在m-1个盘子上(代表有一个盘子上为空的情况);
这样依次拆分,不要忘记函数里面的返回值
还要考虑特殊情况:如果盘子数大于芒果数,则始终会出现空盘子,那么把fun(n,m)写成fun(n,n).
代码如下:
#include<stdio.h>
int fun(int n,int m)
{
if(n==0||n==1||m==1)//n可能会被减小到0或1,m可能会被减小到1
//那么考虑n和m的特殊情况
//当n==1||n==0时,就是没有芒果或者芒果只有一个的情况,此时分类方法只有1个
//当m==1时, 就是盘子数为1的情况,此时分类方法也只有一个
return 1;
else if(n<m)//fun(n,m)在n<m的情况下与fun(n,n)等价
return fun(n,n);
else //拆分为两种情况
return fun(n-m,m)+fun(n,m-1);
}
int main()
{
int n,m,i;
scanf("%d %d",&n,&m);
printf("%d\n",fun(n,m));
return 0;
}
总结
运用递归解题时,要找到规律,把复杂的问题简单化,因为复杂的问题是由很多个小问题组合成的,把递归的规律找出来,并且把返回值找对,问题就迎刃而解了。