POJ 1664

项目弄得差不多了,这几天没事看一下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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值