将m个相同的球全部放到n个相同的盒子里面有几种放法




盒子不能为空,所以可以当成将m-n个球放到n个盒子里,盒子可以为空。

比如将10个球放到5个盒子里,可以当成5个球放到5个盒子里,盒子能为空。接着,再分情况,将球分为

(5,0,0,0,0)

(4,1,0,0,0)或(2,3,0,0,0)

(3,1,1,0,0)或(2,2,1,0,0)

(2,1,1,1,0)

(1,1,1,1,1)

也就是1个盒子不能为空,2个盒子不能为空,3个盒子不能为空,到5个盒子都不能为空。

是不是跟一开始的时候很像,m个球放到n个盒子不能为空?这时候想到了什么?对,递归。

用一个函数fun(m,n)来获取m个球放到n个盒子里不能为空的情况(也可以用能为空的,这里用的是不能为空的)

上面的可以转换成

fun(5,1)+fun(5,2)+fun(5,3)+fun(5,1)+fun(5,0)    //其中n为0的情况即刚好每个盒子分到一个球,这个也要算进去

如果有非递归方法的,欢迎提出来探讨^_^,我自己的理解,不知道对错,有错请指出,谢谢!

#include <iostream>  
06.using namespace std;  
07.  
08.int fun(int m, int n) {  
09.    if (m < n)   //m<n返回0  
10.         return 0;  
11.    if (n == 1 || (m - n) <= 1) //盒子为1时,球只有一个或0(0个即球刚好均分),时都只有一种分配方法  
12.        return 1;  
13.  
14.    int s = 0, count;   //s记录总数,count为递归次数  
15.  
16.    if (m - n < n)       //去掉每个盒子分配的一个球后,球的数量少于盒子数,则只要递归球的个数次  
17.        count = m - n;   //球数少的情况  
18.    else  
19.        count = n; //盒子数少的情况  
20.  
21.    for (int i = 1; i <= count; i++) {  
22.        s += fun(m - n, i); //递归  
23.    }  
24.  
25.    return s;  
26.}  
27.  
28.int main(int argc, char **argv) {  
29.  
30.    cout << "\t";  
31.    for (int i = 1; i <= 15; i++) {  
32.        cout << i << "\t";  
33.    }  
34.    cout << endl;  
35.  
36.    for (int i = 1; i <= 15; i++) {  
37.        cout << i << "\t";  
38.        for (int j = 1; j <= 15; j++) {  
39.            cout << fun(i, j) << "    ";  
40.        }  
41.        cout << endl;  
42.    }  

转自【@AstrayLinux


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值