首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

请问一道概率题

2012-03-09 
请教一道概率题一个箱子里有r个红球和b个蓝球,球的个数之和是奇数。A和B一起玩一个游戏,首先A从箱子里随机

请教一道概率题
一个箱子里有r个红球和b个蓝球,球的个数之和是奇数。A和B一起玩一个游戏,首先A从箱子里随机取出一个球(取到每个球的概率是一样的),然后B从箱子里取出一个蓝球,依次进行下去。

当轮到B取时,箱子里没有可取的蓝球,则B获胜;如果最后一个从箱子里取出的球是蓝球,则A获胜,否则B获胜。

问:给出红球的个数r和蓝球的个数b,求A获胜的概率?



感觉应该dp,谁能详细讲一下?

[解决办法]
用递归实现的,效率不高,呵呵。大家提点改进意见

C/C++ code
double SelectBall(int redBall, int blueBall){    if (!(redBall >= 0 && blueBall >= 0 && (redBall + blueBall) % 2 == 1))    {        printf("Input Error!");        return 0;    }    int nRed = redBall;    int nBlue = blueBall;    double res = 0;    if (blueBall == 0)//蓝球为0个。如果红球大于1,则A必赢(A取后B无球可取),如果红球等于1,则A必输    {        if (redBall == 1)            return 0;        else            return 1;    }    if (redBall == 0)//红球取完了,最后一定是A取到蓝球,获胜    {        return 1;    }    //进入这里的 redball blueball都是大于等于1的    if (blueBall == 1)//只剩一个蓝球,且红球数不为0. 取到蓝球赢,否则进入下一轮    {        return blueBall * 1.0 / (redBall + blueBall) +             redBall * 1.0 / (redBall + blueBall) * SelectBall( redBall - 1, blueBall - 1);    }    //进入这里的redball >= 1, blueball >= 2;    return redBall * 1.0 / (redBall + blueBall) * SelectBall(redBall-1, blueBall-1)         + blueBall * 1.0 / (redBall + blueBall) * SelectBall(redBall, blueBall-2);}int main(){    int redBall = 5;    int blueBall = 10;    while(1)    {        printf("Input Red ball count and Blue ball count:\n");        scanf("%d %d", &redBall, &blueBall);        if (redBall < 0 || blueBall < 0)        {            break;        }        double AWin = SelectBall(redBall, blueBall);        printf("(%d, %d) =%f\n", redBall, blueBall, AWin);    }}
[解决办法]
上代码吧。。SRM408 DIV2 1000
C/C++ code
#include <iostream>using namespace std;double result=0;double pa[1001][4000]={0};class MarblesInABag{public:    double getProbability(int red,int blue)    {        if(red>blue) return 0;        else if(red>1000) return 0;        else if(red==0) return 1;        else if(blue==0) return 0;        else if(pa[red][blue]) return pa[red][blue];        else{            double a=(double)(red)/(double)(red+blue);            double b=(double)(blue)/(double)(red+blue);            pa[red][blue]=a*getProbability(red-1,blue-1)+b*getProbability(red,blue-2);            return pa[red][blue];            }    }};
[解决办法]
尝试了一下,如果球数过大,动态建表比递归方式效率高得多。
#define MAXRED 4011
#define MAXBLUE 8010
double f[MAXRED][MAXBLUE]={0};
double TabSelectBall(int redBall, int blueBall)//返回A获胜的概率
{
int i,j;
for(j=1;j<=blueBall;j++)//所有红球为0的情况,概率为1
f[0][j]=1.0;
for(i=1;i<=redBall;i++)
for(j=0;j<i;j++)
f[i][j]=0.0;
for(int i=1;i<=redBall;i++)
for(int j=i+1;j<=blueBall;j+=2)//蓝球数必须要大于红球数才不为0,
f[i][j]=(f[i-1][j-1]*i+f[i][j-2]*j)/(i+j);
return f[redBall][blueBall];
};

热点排行