放苹果题目要求
把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
分析:对于给定的苹果来说要么数量是大于盘子数量的,要么数量是小于等于盘子数量的,因此我们可以分为两类来讨论。
第一类:盘子数目大于苹果数目,也就是图示第一行。那么肯定会有多余的N-M个盘子,那么我们把这些盘子去掉丝毫不会影响结果。
第二类:当盘子数目小于等于苹果的数目,因为我们要求的是所有可能,因此我们还可以分为两类,有空盘和没有空盘的情况。对于没有空盘的情况也就是第二行的情况,我们可以将每个盘子中的苹果都去掉一个,这样并不会影响最后的结果,也就是M=M-N。对于有空盘的情况,我们可以将其中的一个盘子去掉,也就是N-1. 我们所求的不同放置方式包括有无空盘的各种情况,因此要相加。这就是递归链条
对于递归出口,即盘子等于一的时候,或者是苹果等于零情况。
#include <cstdio>
using namespace std;
/*本题对递归有一定的要求与理解*/
int main()
{
int put_apple(int M,int N);//N是盘子,M是苹果
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
int N,M;
scanf("%d%d",&M,&N);//M是苹果,N是盘子
int K;
K=put_apple(M,N);
printf("%d\n",K);
}
return 0;
}
int put_apple(int M,int N)
{
if(M==0||N==1)return 1;
/*对于任何一种苹果的放法,到最后都能统一的归类为苹果没有了或者盘子只剩一个的情况那么就返回1这一种方法*/
if(N>M) return put_apple(M,M);
/*对于盘子大于苹果的时候,我们把多余的盘子去除掉,完全不会影响有多少中放法,因为始终多了N-M个盘子,所以直接令盘子数
和苹果数目相同。
*/
else
return put_apple(M-N,N)+put_apple(M,N-1);
/*对于苹果有两种放法:
1.如果有空盘子至少有一个空盘子,那么就把空盘子去掉对分类没有影响
2.如果每个盘子都有苹果,那么就每个盘子都减去一个苹果对结果也不会有影响
不管怎样,对于苹果的放法都有这两种,因为一定会有放满和不放满的情况出现。不管是几个苹果几个盘
*/
}