【问题】将M个相同的苹果放入N个相同的盘子
一共有多少种放法?注{1,2,3 }和{3,2,1}是相同的一种。
分析:
所有不同的摆放方法可以分为两类:至少有一个盘子为空和所有盘子都不空。对于至少空着一个盘子的情况,则N 个盘子摆放M 个苹果的摆放方法数目与况,则N 个盘子摆放M 个苹果的摆放方法数目等于N 个盘子摆放M-N 个苹果的摆放方法数目。我们可以据此来用递归的方法求解这个问题。
设f(m, n) 为m个苹果,n 个盘子的放法数目,
则先对n 作讨论,
如果n>m,必定有n-m 个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响;即if(n>m) f(m,n) =f(m,m)。
如果n <= m 时,不同的放法可以分成两类:即有至少一个盘子空着或者所有盘子都有苹果,前一种情况相当于
f(m,n)=f(m,n−1)
f
(
m
,
n
)
=
f
(
m
,
n
−
1
)
后一种情况可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即
f(m,n)=f(m−n,n)
f
(
m
,
n
)
=
f
(
m
−
n
,
n
)
总的放苹果的放法数目等于两者的和,即
f(m,n)=f(m,n−1)+f(m−n,n)
f
(
m
,
n
)
=
f
(
m
,
n
−
1
)
+
f
(
m
−
n
,
n
)
整个递归过程描述如下:
int f(int m , int n)
{
if(n == 1 || m == 0)
return 1;
if(n > m)
return f (m, m);
return f (m , n-1)+f (m-n , n);
}
由上可知:当n=1时,所有苹果都必须放在一个盘子里,所以返回1;当没有苹果可放时,定义为1种放法;递归的两条路,第一条n会逐渐减少,终会到达出口n==1; 第二条m 会逐渐减少,因为n>m 时,我们会return f(m , m) 所以终会到达出口m==0.
【完整代码】
#include<iostream>
using namespace std;
//将M个相同的苹果放入N个相同的盘子
//一共有多少种放法。
int f(int m,int n)
{
if(n==1||m==0)
return 1;
if(n>m)
return f(m,m);
return f(m,n-1)+f(m-n,n);
}
int main()
{
int m,n;
while(cin>>m>>n)
{
cout<<f(m,n)<<endl;
}
}