老王有两个孩子,已知至少有一个孩子是在星期二出生的男孩。问:两个孩子都是男孩的概率是多大?

这个问题其实不难,只是很多时候,尤其在没有任何提示的时候,容易想错。条件概率的题目一定要看清楚条件信息。

问题描述:老王有两个孩子,已知至少有一个孩子是在星期二出生的男孩。问:两个孩子都是男孩的概率是多大?【假设生男生女的概率相等】

刚看到题目的时候,我也愣了一下:一个孩子星期二出生,对于另一个孩子是不是男孩有什么影响吗?

先说一下,这道题的答案是 13 / 27,如果你算出来的不是这个数,那建议你继续往下看看。

思维缜密的项目经理的解题思路

项目经理小李,虽然数学功底不深,编程技术不精,但有个很大的好处是处事不惊,有条不紊。看到题目之后,略加思索,就用最简单的办法弄懂了这个问题,并求出了结果。

首先看如果只知道老王有两个孩子,其他信息都不知道的情况下,两个孩子都是男孩的概率显然是1/4。

再来看看没有“星期二”这个条件的情况,题目变成:老王有两个孩子,已知至少有一个孩子是男孩,问两个孩子都是男孩的概率是多大?那结果显然是1/3。因为在“至少有一个男孩”这样的条件下,只有三种可能:兄妹俩、姐弟俩、兄弟俩。这三种情况是等概率的,而只有一种情况是两个男孩,因此是1/3。

最后再把星期二也考虑进来。还是在上面的基础上扩展,先按照两个孩子的四种可能的性别组合进行划分,然后在每种组合里看看满足有至少一个周二男孩的情况数目:

  • 姐妹俩:不用看了,不满足至少有一个周二男孩的条件。
  • 兄妹俩:那哥哥一定是周二出生的了,妹妹出生的星期数有7种可能。
  • 姐弟俩:弟弟一定是周二出生,姐姐出生的星期数有7种可能。
  • 兄弟俩:兄弟二人出生的星期数总共有7 * 7 = 49种可能,但其中有6 * 6 = 36种都不满足至少有一个人是周二出生的条件,因此实际上有49 - 36 = 13种可能。

因此,满足条件的情况(这里的情况是指综合考虑孩子的性别和出生星期数)总数为7 + 7 + 13 = 27。而其中有13中可能对应于两个孩子都是男孩。因此题目所求概率是13 / 27

没错,13 / 27就是这道题的答案,出现这样的数字是因为已知条件所提供的信息使得样本空间发生了变化(变小了一点儿)。这就是条件概率带来的影响。

博学多才的数据挖掘专家的解题思路

小陈是一个有丰富的数据挖掘和机器学习经验的专家,在听到这个题目的时候,想都没想,干脆地说:“这题简单,用贝叶斯公式就能搞定”。

根据题目,可以认定两个事件,事件A是:至少有一个周二出生的男孩;事件B是:两个孩子都是男孩。题目要求的是P(B|A)即在事件A发生的条件下,事件B发生的概率。根据贝叶斯公式,容易知道:

P(B|A)=\frac{P(AB)}{P(A)}=\frac{P(A|B)P(B)}{P(A)}

依次算出等号右边的各个概率值:

  • 在已知两个孩子都是男孩的条件下,至少有一个是周二出生的男孩:

P(A|B)=1-{(\frac{6}{7})}^2=\frac{13}{49}

  • 两个孩子都是男孩:

P(B)=\frac{1}{4}

  • 至少有一个孩子是周二出生的男孩:

P(A)=1-{(\frac{1}{2}\times\frac{6}{7}+\frac{1}{2})}^2=\frac{27}{196}

因此可以求出:

P(B|A)=\frac{P(A|B)P(B)}{P(A)}=\frac{13}{49}\times\frac{1}{4}\div\frac{27}{196}=\frac{13}{27}​​​​​​​

苦逼的无证程序员的解题方法

无证程序员小周看到题目后,二话不说,写了一小段程序(Python)来计算概率的近似值:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from random import Random

def IsTwoBoys(rand):
  genders = ('M', 'F')
  weekdays = tuple(range(1, 8))
  while True:
    children = [(rand.choice(genders), rand.choice(weekdays)) for i in xrange(2)]
    if ((children[0][0] == 'M' and children[0][1] == 2) or
        (children[1][0] == 'M' and children[1][1] == 2)):
      return True if children[0][0] == children[1][0] == 'M' else False

cnt = 1000000
twoboys = 0
rand = Random()
for i in xrange(cnt):
  if IsTwoBoys(rand):
    twoboys += 1
print 'p(twoboys) =', twoboys, '/', cnt, '=', float(twoboys) / cnt

运行结果,题目所求概率值近似为:0.48213,与13 / 27 = 0.(481)非常接近。

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
按凹入表方式打印一棵树,可以采用深度优先遍历的方式。具体思路如下: 1. 定义一个递归函数,输入参数为当前节点、当前深度和当前位置。 2. 打印当前节点的值,同时在该行末尾加上一个换行符。 3. 如果当前节点有孩子节点,则递归遍历该节点的孩子节点。 4. 如果当前节点还有兄弟节点,则递归遍历该节点的兄弟节点。 5. 在递归遍历孩子节点和兄弟节点之前,需要根据当前深度和位置计算出凹入量,即在该行前面打印几个空格。 下面是具体的算法实现,假设树的节点结构体为: ```c struct TreeNode { int val; struct TreeNode *firstChild; // 第一个孩子节点 struct TreeNode *nextSibling; // 下一个兄弟节点 }; ``` 按凹入表方式打印树的函数如下: ```c void printIndentedTree(struct TreeNode *root) { printIndentedTreeHelper(root, 0, 0); } void printIndentedTreeHelper(struct TreeNode *node, int depth, int pos) { if (node == NULL) { return; } // 计算凹入量 int indent = depth * 4 + pos; for (int i = 0; i < indent; i++) { printf(" "); } // 打印当前节点的值 printf("%d\n", node->val); // 递归遍历孩子节点和兄弟节点 if (node->firstChild != NULL) { printIndentedTreeHelper(node->firstChild, depth + 1, 0); } if (node->nextSibling != NULL) { printIndentedTreeHelper(node->nextSibling, depth, pos + 1); } } ``` 在上述代码中,`depth` 表示当前节点的深度,`pos` 表示当前节点在兄弟节点中的位置。在递归遍历孩子节点和兄弟节点的时候,需要根据深度和位置调整凹入量。同时,注意在打印当前节点的值后,需要加上一个换行符。最后,调用 `printIndentedTree` 函数即可按凹入表方式打印整棵树。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值