项目弄得差不多了,这几天没事看一下ACM的题也是挺不错的~
【思路】:
1、当n>m时,肯定有n-m个盘子是空的,所以fun(m,n) = fun(m,n-m);
2、当n<=m时:
(1)至少有一个盘子是空的,fun(m,n) = fun(m,n-1);
(2)每个盘子都不是空的,则先从所有的苹果中拿出n个苹果,相当于先确保每个盘子都至少有一个苹果。fun(m,n) = fun(m-n,n);
最后fun(m,n) = fun(m,n-1)+fun(m-n,n);
当n=1时,所有的苹果都必须放在一个盘子里,为一种方法。当m=0时,没有苹果可以放,为一种方法。
递归两条路,一条n逐渐减少到n==1退出,另一条m逐渐减少到m==0退出
其实就是组合数学当中将m分成n个数的和,表示成fun(m,n),可以分成两种情况,一种是n个数中至少含有一个0,这样的情况有fun(m,n-1)种,再加一个0即可。另外一种情况是不含0。既然不含有0,则每个数至少为1,即转化为将m-n个数分成n个数,即是fun(m-n,n)。所以fun(m,n) = fun(m,n-1) + fun(m-n,n)。处理好零界条件即可。
至于代码就so easy啦~
#include<stdio.h>
int ans,n,m;
int dp(int m,int n){
if(m<0)
return 0;
if(m==0||n==1)
return 1;
return dp(m-n,n)+dp(m,n-1);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&m,&n);
ans=dp(m,n);
printf("%d\n",ans);
}
return 0;
}