zoukankan      html  css  js  c++  java
  • N个不同球取出M个的组合个数求解

    Technorati 标签: ,

    从N个不同的球中取出M个,一共有多少种取法?

    这个问题是组合数据的基本问题,考虑拿出球是否放回,拿出去的球是否有序,它有4种变体:

    1. 不放回,有序;
    2. 不放回,无序;
    3. 放回,无序;
    4. 放回,有序;

    对于第一种,取出M个球,第一个有N种可能,第二个N-1种可能,依次类推,M个球共有:

    N*(N-1)*(N-2)*..*(N-M+1),

    举个例子:3个同学(A,B,C),从中取出2位同学,那么可能的组合是:

    A B
    C
    B A
    C
    C A
    B

    共计6种,刚好是3*(3-2+1)=6种。

    --------------

    接着看第二种,不放回,无序。由于是无序的,那么上面(无放回有序)的排列显然存在重复,重复的次数正好等于M的全排列。因此它的组合数等于:

    N*…*(N-M+1) / (M*(M-1)*…*1)

    如果用推理计算的方式,我们可以得到一个递归式子:

    f(n,m) = f(n-1,m)+f(n-1,m-1),表示如果包含头元素f(n-1,m-1)种,不包含则为f(n-1,m)种。

    --------------

    第三种,有放回,有序。由于是有序的,M个球,第一个有N种可能,第二个球也有N种可能,。。。。依次类推,因此共有N*N*。。。*N,共M个N相乘。

    举个例子,3个球A,B,C,取出2个,那么可能的组合是:

    A A
    B
    C
    B A
    B
    C
    C A
    B
    C

    --------------

    第四种,有放回,无序,是这里面最麻烦的一种。最直观的做法,是和“无放回”的对应的,类比它们的做法,在结果(3)上除以一个因子:M的全排列。但是这里略有区别,因为在“无放回”的例子中,取出的球是不同的,因此不同的排列是M的阶乘;但是在本case中,取出的球是有重复的,再除以M!就不对了。举个例子,3个球取2个,有放回,无序:

    A A
    B
    C
    B B
    C
    C C

    显然是6种,并不是3*3/2种,后者竟然不是个整数。

    那么正确的建模方式是什么呢?

    首先:把M次取出球当成是M个标签(相同的标签,因为是无序的),把这些标签贴到任意的球上,都贴在一个球上也没有关系。

    然后:把每个球当成是一个盒子,标签当成是盒子里的球

    最后:把盒子一个挨着一个排成一列,如下图所示:“-”代表盒子的底部,“|”代表盒子的壁。

    |-|-|-|

    一种可能的结果是:|o|o|-|,表示A,B被拿出;那么|oo||-|则表示A被拿出2次;

    更一般的,可以得出不同的组合数等于:内壁的个数(N-1)+标签个数(M) 个位置中选出M个用于标签。这显然是无放回无序的问题,也就是C(N-1+M,M)。

    验算一下,设N=3,M=2,则C(4,2)=6。和结果一致。

  • 相关阅读:
    hdu 母牛的故事 递推题
    并查集
    又是矩阵 Uva上的一道 经典题目
    poj 3233 矩阵幂取模
    electronvue + elementui构建桌面应用
    主板cmos 映射表
    高级配置与电源接口 acpi 简介
    警告不能读取 AppletViewer 属性文件的解决方法
    高级 Synth(转载)
    vbs 查看硬件信息代码
  • 原文地址:https://www.cnblogs.com/alphablox/p/5298063.html
Copyright © 2011-2022 走看看