递推题目系列之三放苹果

Time Limit: 2000/1000ms (Java/Others)

Problem 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:

2
8 6
7 3

Sample Output:

20
8
思路:

当n>m:则必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即 if(n>m) f(m,n) = f(m,m)

当n <= m:不同的放法可以分成两类:含有0的方案数,不含有0的方案数

1、含有0的方案数,即有至少一个盘子空着,即相当于 f(m,n)=f(m,n-1);

2、不含有0的方案数,即所有的盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即 f(m,n)=f(m-n,n).而总的放苹果的放法数目等于两者的和,即 f(m,n)=f(m,n-1)+f(m-n,n)

递归出口条件说明:

当n==1时,所有苹果都必须放在一个盘子里,所以返回1;

当m==0(没有苹果可放)时,定义为1种放法;

递归:

1 int fun(int m, int n) //m个苹果放在n个盘子中共有几种方法
2 {
3     if(m==0 || n==1)
4         return 1;
5     if(n>m)
6         return fun(m,m);
7     else
8         return fun(m,n-1)+fun(m-n,n);
9 }

 


AC代码:
 1 #include<stdio.h>
 2 int f(int m,int n)
 3 {
 4     if(m==0)
 5         return 1;
 6     if(n==1)
 7         return 1;
 8     if(n>m)
 9         return f(m,m);
10     if(n<=m)
11         return f(m,n-1)+f(m-n,n);
12 }
13 int main()
14 {
15     int t,m,n;
16     scanf("%d",&t);
17     while(t--)
18     {
19         scanf("%d%d",&m,&n);
20         printf("%d\n",f(m,n));
21     }
22     return 0;
23 }

 

posted on 2017-01-25 22:43  小青虫  阅读(208)  评论(0编辑  收藏  举报