现在的位置: 首页 > 综合 > 正文

POJ 1664

2014年01月22日 ⁄ 综合 ⁄ 共 724字 ⁄ 字号 评论关闭
项目弄得差不多了,这几天没事看一下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;
}

抱歉!评论已关闭.