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。和结果一致。

时间: 2024-11-08 19:55:25

N个不同球取出M个的组合个数求解的相关文章

nyoj 找球号三(除了一个数个数为基数,其他为偶数,编程之美上的)

#include<iostream> #include<stdio.h> using namespace std; int main() { int len; while(cin>>len) { int ans; len--; cin>>ans; while(len--) { int a; cin>>a; ans=ans^a; } cout<<ans<<endl; } system("pause");

[单选题]以下哪个函数是用来取出PHP数组的元素个数的

array_reverse min count max 答案 C 实例 以相反的元素顺序返回数组: <?php $a=array("a"=>"Volvo","b"=>"BMW","c"=>"Toyota"); print_r(array_reverse($a)); ?> 运行实例 定义和用法 array_reverse() 函数以相反的元素顺序返回数组. 说

从0~100之间随机取出不重复的10个数

目前只学会两种简单的方法 第一种利用数组长度可改写的特点 思路:可以从0到100的数用for循环出来放在一个数组中,然后将这100个数利用sort()随机打乱,然后通过将这个数组的length改写为10,便取到了10个不同的数. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title&g

【题解】数球

题目描述 小 A 有 \(n\) 个球,编号分别为 \(1\) 到 \(n\),小 A 每次都会从 \(n\) 个球中取出若干个球,至少取一个,至多取 \(n\) 个,每次取完再放回去,取出的球需要满足以下两个条件: 每次取出的球的个数两两不同. 每次取出的球的集合两两不包含. 包含是指,对于两次取球,取的数目少的那次取球的所有球都出现在取的数目多的那次取球中. 例如 \(\{1,2\}\) 和 \(\{1,2,4\}\),\(\{1,2\}\) 和 \(\{2,3\}\) 则不算作包含. 而小

M个元素集合取出N个不重复排列组合

#include<stdio.h>#include<string.h> int check(char *str, int l){     for(int i=0; i<l ;i++)     {          for(int j=0; j<l ;j++)          {               if(j==i)                continue;               if(str[i]==str[j])               

数据挖掘中所需的概率论与数理统计知识

http://blog.csdn.net/v_july_v/article/details/8308762 数据挖掘中所需的概率论与数理统计知识 (关键词:微积分.概率分布.期望.方差.协方差.数理统计简史.大数定律.中心极限定理.正态分布) 导言:本文从微积分相关概念,梳理到概率论与数理统计中的相关知识,但本文之压轴戏在本文第4节(彻底颠覆以前读书时大学课本灌输给你的观念,一探正态分布之神秘芳踪,知晓其前后发明历史由来),相信,每一个学过概率论与数理统计的朋友都有必要了解数理统计学简史,因为,

三色球问题

若一个口袋里放了12个球,3个红的,3个黄色的,6个绿色的,从中任意选择8个,问有多少不同的搭配? 1:问题的分析 取红色的球可以有4种可能:0个,1个,2个,3个 取黄色的球可以有4种可能:0个,1个,2个,3个 取绿色的球可以有7种可能:0个,1个,2个,3个,4个,5个,6个 我们只需要穷举每一种可能的情况就行了 package 三色球; import java.util.Scanner; public class Main { public static void main(String

推荐系统中所需的概率论与数理统计知识

前言 一个月余前,在微博上感慨道,不知日后是否有无机会搞DM,微博上的朋友只看不发的围脖评论道:算法研究领域,那里要的是数学,你可以深入学习数学,将算法普及当兴趣.想想,甚合我意.自此,便从rickjin写的"正态分布的前世今生"开始研习数学. 如之前微博上所说,"今年5月接触DM,循序学习决策树.贝叶斯,SVM.KNN,感数学功底不足,遂补数学,从'正态分布的前后今生'中感到数学史有趣,故买本微积分概念发展史读,在叹服前人伟大的创造之余,感微积分概念模糊,复习高等数学上册,

阿里巴巴2016数据挖掘工程师真题在线测

1.想要了解上海市小学生的身高,需要抽取500个样本,这项调查中的样本是? A.从中抽取的500名学生的身高 B.上海市全部小学生的身高 C.从中抽取的500名小学生 D.上海市全部小学生 2.以下对k-means聚类算法解释正确的是 A.能自动识别类的个数,随即挑选初始点为中心点计算 B.能自动识别类的个数,不是随即挑选初始点为中心点计算 C.不能自动识别类的个数,随即挑选初始点为中心点计算 D.不能自动识别类的个数,不是随即挑选初始点为中心点计算 3.以下哪个是常见的时间序列算法模型 A.R