一个不简单的概率问题
我们办公室里放了四盒扑克,以前是在休息时玩一种扑克游戏用的。这种玩法需要 8 个人进行,同时用 4 副牌。玩完后我们洗乱放进了 4 个牌盒里。现在流行打桥牌,桥牌只用一副 52 张就够了,所以我决定清一副出来。清牌的时候,偷懒不想把 4 个牌盒里的牌全倒出来,然后我脑子里就出现了这么一个问题。
假设牌是完全洗乱,均匀随机分布在 4 个牌盒里的,而且每个盒子里都是均等的 54 张。那么需要打开几个牌盒,才能有很大几率(>90%)的保证从中得到一整副牌呢?
当时一个帮忙清牌的牌友说,大概打开 2 盒就够了。我的直觉告诉我,2 盒应该不够,3 盒应该勉强吧。但实际情况是,我们从 3 盒牌里只找到了独立的 53 张。第 54 张牌是从第 4 个盒子里找到的。
当时觉得这个概率问题很有趣,应该也不复杂。便在纸上划了一下。推导了如下公式:
假设有 n 盒洗乱的牌,当我打开其中的 m 盒,从中凑齐一副完整的概率应该是
(1- ( (n-m)/n )^n ) ^ 54
把 m=2 n=4 代入算了一下,概率只有 3%
m=3 n=4 的时候,概率有 81%
今天( 5 月 1 日)重新想了一下,这个问题并不简单。原因下面 zf 的留言里也写了。我的数学不是那么的好,推导公式恐怕比较麻烦。好在我们有 C 语言这个工具,我用 C 写了个程序求解:
#include "stdio.h"
#define CARD 54
#define N 4
#define M 3
static int assemble_table[N+1];
static double probability_table[CARD*N][CARD*N];
void init_probability_table()
{
int i,j;
for (i=0;i0) {
for (i=n;i=0) {
return probability_table[total-1][part-1];
}
if (part==N && total==N) {
return 1;
}
p+=draw_ncard(total,part,N);
for (i=N-1;i>=0;i--) {
double t=draw_ncard(total,part,i);
if (t!=0) {
t*=probability(total-N,part-i);
p+=t;
}
}
probability_table[total-1][part-1]=p;
return p;
}
double calc()
{
int total=N*CARD;
int part=(N-M)*CARD;
double p=probability(total,part);
return 1-p;
}
int main()
{
init_assemble_table();
init_probability_table();
printf("%lf\n",calc());
return 0;
}
程序写的很粗糙,不过能计算出答案就够了。代入 N=4 M=2 计算了一下,结果是 0.019088 N=4, M=3 时概率是 0.820296
跟前面那个错误公式得到的答案差不太多,我觉得原因是牌的张数(54) 远大于牌的分组的缘故。
引申一个可以被口算的题:有四张牌,两张大王两张小王,摸两张牌,摸到一对的可能性有多大?我问了好几个人,居然第一反应是 50% (._.!) 当然大家想过 1 分钟后,就可以得到正确的答案了。
