问题描述:
把M个苹果放在N个盘子中,允许有盘子为空,共有多少种放置的方法。1.2.1和2.1.1是同样的放置方法。
输入:
第一行是测试数据的数目Num(0<=Num<=20)。以下每行均包含2个整数M和N,以空格分开。1<=M,N<=10。
输出:
对输入的每组数据M和N,用一行输出相应的K。
样例输入:
1
7 3
样例输出:
8
问题的思考及解决:
这题的思考模式和爬楼梯有点相似,也是类似于排列组合的问题,但是又不能用排列组合的思想来处理这个问题,需要用递归的思想来处理这个放置苹果的问题。
这个题目有3个需要考虑的问题点:
1)苹果和盘子数目的大小是否影响递归的思路
2)苹果和盘子如何进行递归求解摆放的数量
3)递归终止的条件
先从第一个问题考虑:当盘子数多于苹果数时,无论怎么放置,必然会有盘子多出来的。我们假设写个函数叫PlaceApple(m,n),返回值为放置的方法,那么当m<n时,有PlaceApple(m,n)=PlaceApple(m,m)。
那么如果m>n时,如何处理呢,此时我们会发现,在这种情况下,可能有盘子多出来,也可能没有盘子多出来。苹果放置的方法就为没有空盘子的情况和有空盘子的情况的总和,即为:PlaceApple(m,n)=PlaceApple(m, n - 1) + PlaceApple(m - n, n)。PlaceApple(m, n - 1)为空置1个盘子时的放置方法数,继续递归求解PlaceApple(m, n - 1),可以将所有有空盘子的放置方法求解出。PlaceApple(m - n, n)为没有空盘子的情况的放置方法:先将n个盘子放上一个苹果,然后再随意放置m-n个苹果。二者相加,即为我们要求解的苹果放置的总数。这一步是本题的核心步骤。
最后考虑一下递归的终止条件。首先,盘子和苹果数肯定不能为负数,最小的情况为0。当盘子的数量为0时,无论有几个苹果,均无法放置,即当n=0时,放置的方法为0个。当苹果数为0时,则当前的放置方式是唯一的,即放置方法为1。递归式中有PlaceApple(m - n, n),当m<n时,我们会返回PlaceApple(m,m),所以在PlaceApple(m - n, n)中,m-n必然是>=0的,所以在进行递归终止条件判断时,我们把m和n设置为与0比较即可。
代码
#include <iostream>
using namespace std;
int PlaceApple(int m, int n)//m为苹果数,n为盘子数
{
if (n > m)//当盘子数大于苹果数时,则必有盘子为空的
return PlaceApple(m, m);
if (m == 0)
return 1;
if (n == 0)
return 0;
return
PlaceApple(m, n - 1) + PlaceApple(m - n, n);//苹果的总数为:有盘子为空的放法+没盘子为空的放法
}
void main()
{
int Num, m, n;
cin >> Num;
while (Num--)
{
cin >> m >> n;
cout << PlaceApple(m, n) << endl;
}
}
来源:CSDN
作者:Crazy_Tommy
链接:https://blog.csdn.net/qq_35454197/article/details/104104535