首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

盒子放球排列组合有关问题请问

2012-04-13 
盒子放球排列组合问题请教~n个盒子,m个球,把m个球放到n个盒子中,盒子可以为空,列出所有可能排列组合~如2个

盒子放球排列组合问题请教~
n个盒子,m个球,把m个球放到n个盒子中,盒子可以为空,列出所有可能排列组合~

如2个球放到3个盒子中
2 0 0
1 1 0
1 0 1
0 1 1
0 2 0
0 0 2



数学没学好,请教各位老大~谢谢的说,解决马上给分~

[解决办法]
问题可以转化成:求方程 x1+x2+x3+...+xn=m 的非负整数解的个数。

可以采用“挡板法”来解决。

记C(m,n)为n个中选m个的组合数。
求非负整数解,相当于在m个1中间插入n-1个0,这n-1个0将m个1分成了n部分,第i部分中的1的个数,就是xi对应的值。换个角度,上述一共有 m+n-1个元素(0或1),只要确定m个1的位置或者n-1个0的位置,就得到方程组的一个解。

于是解的个数为:C(m,m+n-1)。
[解决办法]
这其实是一个n进制数的问题
假定存在一个m位的n进制数,他的k位上的数字表示第k个球所在盒子的编号,可以证明这个m位的n进制数和盒子的排列是一一对应的

我们知道,对于这种题目,可能的组合数为n^m,那么你只要把0->n^m-1的数转换成n进制数,再检查对应的每位数既可知道每个球所在的盒子

所以唯一的难点就是整数转换成n进制数的问题,这个好像不是难题哦,学过计算机原理的都应该知道除余法
也就是对于整数x, x%n表示n进制数个位上的数字,要求更高位的数字,要用x= x/n迭代
[解决办法]
求所有组合的程序:

C/C++ code
#include <cstdlib>#include <iostream>int   *list;int   n;void  f( int len, int sum ){      int  i;      if( sum==0 ){          for( i=0; i<len; ++i )               std::cout<<list[i]<<" ";          for( ; i<n; ++i )               std::cout<<0<<" ";          std::cout<<std::endl;          return;      }      if( len==n-1 ){          list[len]=sum;          for( i=0; i<=len; ++i )               std::cout<<list[i]<<" ";          std::cout<<std::endl;          return;      }      for( i=0; i<=sum; ++i ){           list[len]=i;           f( len+1, sum-i );      }};int main( ){    int  m;    std::cin>>m>>n;    list=new int[n];    f( 0, m );    delete list;    system("PAUSE");    return EXIT_SUCCESS;} 

热点排行