POJ 1664 放苹果
Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u
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
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;
在整个递归的过程中,要考虑的情况只有两种,一种是m和n的大小比较,另一种就是整个的递归出口。
#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;
}