随机抽取的概率问题


题目描述:
一个袋子里,有m个黑球,n个白球
每次随机同时取两个,如果是两个黑球,就不用放回
如果是两个白球,就放回一个黑球
如果是一个黑球一个白球,就放回一个白球
问最后仅剩下的是黑球的概率为?

输入:
多组测试数据,每组一行
每行为m与n (1 <= m,n <= 1e9),
直到EOF

输出:
输出概率值,精确到小数位后三位

样例输入:
1 1
1 2

样例输出:
0.000
1.000

注:不要被概率吓倒,其实是简单题啦 :)
已邀请:

chenweizhi - 程序猿

赞同来自: nic122333


我来试解一下。
1、如果是两个黑球,就不用放回
2、如果是两个白球,就放回一个黑球
3、如果是一个黑球一个白球,就放回一个白球

这三个抽取条件,分析下来,分别是
1、拿走2黑球
2、拿走2白球,如果手上没有黑球,袋子里黑球数量不变
3、拿走1黑球
由上面三条可知,要袋子里面剩下的是黑球,白球必须可以拿完,也就是说,白球必须为2的倍数,否则无论怎么拿概率都是0。

考虑最简单的情况,2白 1黑 概率为1 2白 2黑 概率为5.0/6.0。
以上面三种情况做为终止条件,编写递归函数:
//bbInHand 手上黑球的数量
float GetBlackBallProbability(int m,int n,int bbInhand)
{
    //以防万一
    if (m < 0 || n < 0)
    {
        return .0f;
    }

    //白球不是2的倍数
    if (n % 2 == 1)
    {
        return .0f;
    }

    //简单情况
    if(m==1 && n==2)
    {
        return 1.0f;
    }
    else if(m==2 && n==2)
    {
        return 5.0f/6.0f;
    }
    else
    {
        int iBalls=m+n;
        float fBallBB = .0f;  //黑黑
        float fBallBW = .0f;  //黑白
        float fBallWW = .0f;  //白白
        float ret = .0f;

        if (m>=2)
        {
            fBallBB = ((m-1)*m *1.0f) / (iBalls*(iBalls-1));
            ret += fBallBB*GetBlackBallProbability(m-2,n,bbInhand+2);
        }

        if (n>=2)
        {
            fBallWW = ((n-1)*n*1.0f) / (iBalls*(iBalls-1));

            if (bbInhand > 0)
            {
                ret += fBallWW*GetBlackBallProbability(m+1,n-2,bbInhand-1);       
            }
            else
            {
                ret += fBallWW*GetBlackBallProbability(m,n-2,bbInhand); 
            }

        }

        if (n>=1 && m>=1)
        {
            fBallBW = (m*n*1.0f) / (iBalls*(iBalls-1));
            ret += fBallBW*GetBlackBallProbability(m-1,n,bbInhand+1);
        }


        return ret;
    }
}


PS:代码的排版好蛋疼

要回复问题请先登录注册