POJ1664将M个苹果分给N个盘子

POJ1664

题目:

Description

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

第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
Sample Input

1
7 3
Sample Output

8

对输入的每组数据M和N,用一行输出相应的K。
(摘自http://poj.org/problem?id=1664)

解决函数:
int num(int apple,int baket)
{
if(baket<=0||apple<0)
return 0;
if(apple1||baket1)
return 1;
return num(apple,baket-1)+num(apple-baket,baket);
}

本质: 讨论N个自然数(>=0)合为M时,N的组合的可能。如M为3,N为3,N的组合可能就有{0,0,3},{0,1,2},{1,1,1}三种(忽略重复情况)
分析:(以递归形式为手段展开讨论)
首先阅读题干可知我们讨论的就是N个数字的组合问题
而已知N或M为1的情况下,组合只有一种。此外{1,5,1}与{5,1,1}为一种情况。
为了避免重复,我们可以对N个数字由小到大展开讨论,后一个数比前一个数大或二者相等。如{x,y,z},x<=y<=z。设置函数 int num(M,N);(m表示剩余的苹果,N表示剩下的篮子)
则有(1)x=0的时候,y+z=M. N=N-1;
(2)x不为0的时候,y和z一定不比x小,如x为1,{x,y,z}={1,1+a,1+b}
在对分类的讨论上{1,1+a,1+b}=={0,a,b} 二者分类的情况相同(a+b=M-N,N数目不变)
即N=N,M=M-N;
此外1是最基本的正整数,所以我们可以由1为单位从0开始逐渐递增最小数字的大小
综合(1)(2),做出如下num函数雏形

     int num(M,N){ return num(M,N-1)+num(M-N,N);}
     //num(M,N-1)是对最小数为0情况的讨论   num(M-N,N)是对最小数不为0的讨论,
     
     结合本题例子(7果3盘子)
     重复两次num(M,N-1) 就会有 num{7,1}  
     重复2次num(M-N,N)就会有num(1,3)实际代表{2,2,3}情况
     出现上述两种情况的时候我们就可以归类为函数返回值为1,
     也就是if(N==1||M==1) return 1;
     但是同时这也会产生一些错误数据 
     如num(M-N,N)重复三次,就会有num(-2,3)
     而重复十次num(M,N-1)也会有num(7,-7)
     所以用if(N<=0||M<0)return 0; 来防止函数产生错误数据
	
	然后写到这里我想大家也许会有疑问,为什么把N小于等于0与return0挂钩,而M却只有小于0.
	其实大家不妨想想M=0的情况,这里M减小只有一种途径,即M-N,M等于0时,可以说是M平分给了N个盘子(这里的N 未必是一开始的N),而后M=0,N>0,   则(num(0,N-1)+num(0-N,N))==num(0,N-1)+0=num(0,1+a)=num(0,1)=1,并不会产生错误函数。
	综上  构建出递归函数

int num(int apple,int baket)
{
if(baket<=0||apple<0)
return 0;
if(apple1||baket1)
return 1;
return num(apple,baket-1)+num(apple-baket,baket);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值