POJ 1664 放苹果

Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u

Description

M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)511151 是同一种分法。

Input

第一行是测试数据的数目t0 <= t <= 20)。以下每行均包含二个整数MN,以空格分开。1<=MN<=10

Output

对输入的每组数据MN,用一行输出相应的K

Sample Input

1
7 3

Sample Output

8

 

 

解题分析:

设f(m,n)为m个苹果,n个盘子的不同放法的数目,先对n进行分析:

1、当n〉m时,由于多余的盘子没用,故可将多余的盘子去了,即f(m,n)=f(m,m)。

2、当n<=m,分两种情况:1.至少有一个盘子是空的,则f(m,n)=f(m,n-1);2.所有的盘子都是满的,由题意知5,1,1和1,5,1 是同一种分法。因此,从每一个盘子里面拿出一个不影响其放的数目,则此种情况下f(m,n)=f(m-n,n),则在n〈=m的情况下,总的数目f(m,n)=f(m,n-1)+f(m-n,n);

递归出口的说明:

当苹果没有的时候,即m=0的时候,定义为一种情况。当n=1时,所有的苹果都得放在同一个篮子里,因此也只有一种情况。

在递归的过程中,第一种情况,n的值在减少,因此最终会减到n=1时,在第一二种情况下,m的值在减少,最终m=0

在整个递归的过程中,要考虑的情况只有两种,一种是mn的大小比较,另一种就是整个的递归出口。

#include <stdio.h>

int s(int m,int n)

{

       if(m==0||n==1)

       return1;

       if(n>m)

       returns(m,m);

       else

       returns(m,n-1)+s(m-n,n);

}

int main()

{

       intt,x,m,n;

       scanf("%d",&t);

       while(t--)

       {

              scanf("%d%d",&m,&n);

              x=s(m,n);

              printf("%d\n",x);

       }

      

       return0;

}