CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  专题开发/技术/项目 >  数据结构与算法

求助:一个取球问题的算法,请各位高手指点一下。

楼主lsh1000()2006-12-08 18:12:51 在 专题开发/技术/项目 / 数据结构与算法 提问

我编写了一个程序,速度太慢,如果是40个球,有两个篮子都要计算好几个小时,希望各位有C/C++程序的能贴一个上来,多谢了。题目如下:  
   
  假如有N个球,要放入a个不同的篮子中,球必须全部放完,请问怎么求有几种放的方式(球不记先后顺序)。  
   
  即当有4个球,要放入3个篮子时,结果为  
  序号         第一个球所在的篮子号   第二个球所在的篮子号   第三个球...   第四个球...  
   
  0               1111       //四个球都在1号篮子里  
  1               2111       //2,3,4号球在1号篮子里,1号球在2号篮子里  
  2               1211       //1,3,4号球在1号篮子里,2号球在2号篮子里  
  3               1121  
  4               1112  
  5               2211  
  6               2121  
  7               2112  
  8               1221  
  9               1212  
  10             1122  
  11             2221  
  12             2212  
  13             2122  
  14             1222  
  15             2222  
  16             3111  
  17             3211  
  18             3121  
  19             3112  
  20             3221  
  21             3212  
  22             3122  
  23             3222  
  24             1311  
  25             2311  
  26             1321  
  27             1312  
  28             2321  
  29             2312  
  30             1322  
  31             2322  
  32             1131  
  33             2131  
  34             1231  
  35             1132  
  36             2231  
  37             2132  
  38             1232  
  39             2232  
  40             1113  
  41             2113  
  42             1213  
  43             1123  
  44             2213  
  45             2123  
  46             1223  
  47             2223  
  48             3311  
  49             3321  
  50             3312  
  51             3322  
  52             3131  
  53             3231  
  54             3132  
  55             3232  
  56             3113  
  57             3213  
  58             3123  
  59             3223  
  60             1331  
  61             2331  
  62             1332  
  63             2332  
  64             1313  
  65             2313  
  66             1323  
  67             2323  
  68             1133  
  69             2133  
  70             1233  
  71             2233  
  72             3331  
  73             3332  
  74             3313  
  75             3323  
  76             3133  
  77             3233  
  78             1333  
  79             2333  
  80             3333  
  问题点数:50、回复次数:21Top

1 楼spirit_sheng(老盛)回复于 2006-12-08 19:33:13 得分 0

首先,   你这做法就有问题,   既然球不分先后顺序,   那就不能象你这么做  
  你这种做法是球分先后顺序的,   如果还应分先后顺序,   则结果为   a^N  
  就向你上面这种做法,   3^4=81  
  Top

2 楼spirit_sheng(老盛)回复于 2006-12-08 19:40:46 得分 10

如果球不分先后顺序,   则结果为   C(a+N-1,   a-1)  
   
  可以如下考虑,   将篮子和球沿一条直线排开,   每个篮子后面跟着放入其中的球,   篮子依序摆放  
  则每一种摆放方式与结果中的一种放入方式一一对应  
  由于第一个位置必须是第一个篮子,   所以种数为在剩下   a+N-1   个位置中,   挑a-1个位置放篮子,   其种数为   C(a+N-1,   a-1)  
  Top

3 楼spirit_sheng(老盛)回复于 2006-12-08 19:42:43 得分 0

如果按你的理解,   则40个球,   两个篮子,   则结果一共有   2^40种,   当然要计算很长时间了  
  但如果是第二种,   则C(41,1)=41种Top

4 楼litaoye()回复于 2006-12-08 23:35:36 得分 5

问题一:球是否有编号?如果没有编号,只是每个篮子里面球个数的问题,计算量要小很多。  
  问题二:篮子是否有编号,如果没有编号,计算量又会小很多。Top

5 楼spirit_sheng(老盛)回复于 2006-12-09 09:47:06 得分 0

其实题目说得已经很清楚了  
  一:   "(球不记先后顺序)"  
  二:   "放入a个不同的篮子中"Top

6 楼MagicPeng(彭彭)回复于 2006-12-09 12:22:55 得分 0

恩     排列     组合Top

7 楼lsh1000()回复于 2006-12-09 12:34:22 得分 0

呵呵,多谢各位了。可能是我描述有问题,说的不是很清楚。  
  我这里做的是有编号的,即球是从1号-N号   ,篮子也是从1号-A号,遍历所有可能的结果。但是球必须要全部放完,即某一个球一定在某一个篮子里。  
  因为可能计算的数目比较大,我原来写的程序效率不是很高,想看看各位有没有好的方法能更快一些。  
  Top

8 楼lsh1000()回复于 2006-12-09 12:52:44 得分 0

呵呵,多谢各位了。可能是我描述有问题,说的不是很清楚。  
  我这里做的是有编号的,即球是从1号-N号   ,篮子也是从1号-A号,遍历所有可能的结果。但是球必须要全部放完,即某一个球一定在某一个篮子里。  
  因为可能计算的数目比较大,我原来写的程序效率不是很高,想看看各位有没有好的方法能更快一些。  
  (还要考虑的:设立一个数组,记录每一个篮子的装球范围,也就是每一个篮子必须装I-J个球,即1号篮子必须装2-4个球,2号篮子必须装1-3个球,3号篮子必须装0-2个球......,对这种情况如何实现。)  
   
  有源代码的最好能贴一个上来。多谢了。  
   
  我原来想的是     对所有的球用递归的方法来进行深度优先遍历,每一个球必在1-A个篮子中,即对任一个球遍历1-A次。  
   
  (下面这个是没有设立装球范围数组的,如果要考虑每个篮子装球范围的需要怎么做)  
  即当有4个球,要放入3个篮子时,结果为  
  序号         第一个球所在的篮子号   第二个球所在的篮子号   第三个球...   第四个球...  
   
  0               1111       //四个球都在1号篮子里  
  1               2111       //2,3,4号球在1号篮子里,1号球在2号篮子里  
  2               1211       //1,3,4号球在1号篮子里,2号球在2号篮子里  
  3               1121  
  4               1112  
  5               2211  
  6               2121  
  7               2112  
  8               1221  
  9               1212  
  10             1122  
  11             2221  
  12             2212  
  13             2122  
  14             1222  
  15             2222  
  16             3111  
  17             3211  
  18             3121  
  19             3112  
  20             3221  
  21             3212  
  22             3122  
  23             3222  
  24             1311  
  25             2311  
  26             1321  
  27             1312  
  28             2321  
  29             2312  
  30             1322  
  31             2322  
  32             1131  
  33             2131  
  34             1231  
  35             1132  
  36             2231  
  37             2132  
  38             1232  
  39             2232  
  40             1113  
  41             2113  
  42             1213  
  43             1123  
  44             2213  
  45             2123  
  46             1223  
  47             2223  
  48             3311  
  49             3321  
  50             3312  
  51             3322  
  52             3131  
  53             3231  
  54             3132  
  55             3232  
  56             3113  
  57             3213  
  58             3123  
  59             3223  
  60             1331  
  61             2331  
  62             1332  
  63             2332  
  64             1313  
  65             2313  
  66             1323  
  67             2323  
  68             1133  
  69             2133  
  70             1233  
  71             2233  
  72             3331  
  73             3332  
  74             3313  
  75             3323  
  76             3133  
  77             3233  
  78             1333  
  79             2333  
  80             3333Top

9 楼spirit_sheng(老盛)回复于 2006-12-09 13:33:52 得分 0

首先楼主搞清楚,   是只要求出有多少种,   而是要列出每一种的情况  
  如果要列出每一种的情况,   而且球有分别,   例如,   对于40个球,   如果每个筐放20个球,   也有  
  C(40,   20)=137,846,528,820   如果要输出每种情况,   这么大的数量,   打印显然没意义,   如果是保存,   假设你最优的保存方式,   每个球用1个bit表示,   那每种结果需要40bit,   即5字节,   那你所有这些结果需要   137,846,528,820   *   5   Bytes   那需要   642   GBytes   的磁盘空间才能保存,   你认为这样的输出有意义吗?  
  如果只需要计算次数,   那就简单多了,   根据数学公式计算即可,   不需要象你这样遍历来解决问题Top

10 楼lsh1000()回复于 2006-12-09 13:47:21 得分 0

呵呵,多谢各位的帮助。其实并不需要这么多的球,只需要计算10-15个球,篮子数目2-4个,但是必须要全部遍历所有的结果并且保存。  
  也不需要用bit来保存,使用一个INT型数组来存放一个遍历结果就可以了。  
  计算次数是可以根据数学公式,但是我需要列出所有的情况。  
  当然球数目和篮子数目是自己确定的,不需要设这么大的球数,但是我是想找一种方法来尽量提高效率,使计算尽可能快一些就行。  
  我需要简洁一些的代码,并且效率要高一些。  
  Top

11 楼nako_ruru(娜可露露)回复于 2006-12-09 22:37:44 得分 0

spirit_sheng(老盛)   ,你並沒有考慮完善樓主的想法。  
   
  樓主的結果裡面是沒有空籃子的。在這種情況下該方法數應該為C(N   -   1,   a   -   1)  
  Top

12 楼ctu_85(青灯照壁人初睡,冷雨敲窗被未温)回复于 2006-12-11 11:02:38 得分 0

其实答案很简单  
  结果是:  
  a   exp   (N)  
  对于本题来说就是3的4次方啊  
  不存在C(N   -   1,   a   -   1)的结果Top

13 楼ctu_85(青灯照壁人初睡,冷雨敲窗被未温)回复于 2006-12-11 11:11:00 得分 5

这个题目的解答方法是:  
  设4个非负树x1,x2,x3,x4  
  求解sum=x1+x2+x3+x4的结果在4-16范围内所有可能的取值  
  答案是无意义的,因为本题不存在任何解答技巧问题  
  如果限制了蓝筐的容量为h,那么本题的结果可以归纳为对拥有h+1高度的N叉树(N为篮子数目)的形态结构问题  
  相信这个解答用Recrusive解决会很简单的Top

14 楼mathe()回复于 2006-12-11 11:28:44 得分 30

其实就是将所有N位a进制数输出就可以了。  
  有很多种方法,其实本质上效率都差不多。  
   
   
  void   output(int   index,   int   x[]){  
      int   i;  
      printf("%d\t",index);  
      for(i=0;i<N;i++)printf("%d",x[i]+1);  
      printf("\n");  
  }  
  int   buf[N];  
  int   index=0;  
  for(i=0;i<N;i++)buf[i]=0;  
  for(;;index++){  
        output(index,buf);  
        for(i=N-1;i>=0&&buf[i]==a-1;i--)buf[i]=0;  
        if(i<0)break;  
        buf[i]++;  
  }Top

15 楼zssxfc()回复于 2006-12-11 13:28:02 得分 0

zzzzTop

16 楼vividw(vividw)回复于 2006-12-11 16:27:42 得分 0

同意     mathe()     直接生成结果   解空间映射Top

17 楼lsh1000()回复于 2006-12-11 16:52:00 得分 0

这是我原来写的,使用了递归,效率不是太好。球越多,递归就越深。使用time函数检测了一次两个程序的时间开销,  
  debug:   我的是1485,mathe的是489  
  release:我的是318,mathe的是234  
  /////////////////////////////////////////////////////  
  struct   MyData  
  {  
  INT   nNumOfBall;    
  INT*   pValue;  
   
  INT   nNumOfBox;  
  };  
   
  INT   DealData(MyData*   pData)  
  {  
  static   INT   njishu   =   0;  
   
  printf("%d\t",njishu++);  
   
  for   (INT   i=1;   i<=pData->nNumOfBall;i++)  
  {  
  printf("%d",pData->pValue[i]);  
  }  
   
  printf("\n");  
  }  
   
  INT   TraverseBox(MyData*   pData,   INT   nCurBall)  
  {  
  for   (INT   i=1;   i<=pData->nNumOfBox;   i++)  
  {  
  pData->pValue[nCurBall]   =   i;  
   
  TraverseBall(pData,nCurBall+1);  
  }  
   
  return   TRUE;  
  }  
   
  INT   TraverseBall(MyData*   pData,   INT   nCurBall)  
  {  
  if   (nCurBall   >   pData->nNumOfBall)  
  {  
  DealData(pData);  
   
  return   TRUE;  
  }  
   
  TraverseBox(pData,nCurBall);  
   
  return   TRUE;  
  }  
   
  int   main()  
  {  
  MyData   data;  
   
  data.nNumOfBall   =   10;  
  data.nNumOfBox   =   3;  
   
  data.pValue   =   (INT*)malloc((data.nNumOfBall+1)*sizeof(INT));  
  if   (NULL   ==   data.pValue)  
  {  
  return   0;  
  }  
  memset(data.pValue,0,(data.nNumOfBall+1)*sizeof(INT));  
   
  TraverseBox(&data,1);  
   
  free(data.pValue);  
   
  return   0;  
  }Top

18 楼lsh1000()回复于 2006-12-11 17:05:05 得分 0

多谢mathe了,你的方法很不错,代码也很简洁,而且还没有递归调用。呵呵,多谢了。Top

19 楼lsh1000()回复于 2006-12-11 17:30:11 得分 0

多谢各位,结贴。呵呵,多谢了。Top

20 楼tdktdktdk()回复于 2006-12-12 08:49:02 得分 0

用排列组合:Power(a,N-1)/N!Top

21 楼daidodo(火箭发射机)回复于 2006-12-12 09:57:15 得分 0

C(N   +   1,a)Top

相关问题

关键词

得分解答快速导航

  • 帖主:lsh1000
  • spirit_sheng
  • litaoye
  • ctu_85
  • mathe

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo