Light OJ 1050 Marbles (概率DP)

75 篇文章 0 订阅

题意:A和B玩一种游戏,箱子里有两种球,红球和蓝球,球的总数是奇数,A先手,轮到A时,A从箱子里随机取一球,轮到B时,B从中拿出一个蓝球,如果轮到B时,已经没有蓝球,则B胜出。

如果取出的最后一个球是蓝球(无论是A取还是B取),则A胜出,反之B胜出。求A获胜的概率。

解析:显然 如果剩下奇数个球,这一轮肯定是A,反之是B。

dp[i][j]为有i个红球j个蓝球A获胜的概率。

则递推关系:

 若(i+j)&1=1 dp[i][j+1] += dp[i][j],反之,dp[i][j+1] = (j+1)*dp[i][j]/(i+j+1) ,dp[i+1][j] = (i+1)*dp[i][j]/(i+j+1) 

这题做麻烦了  写循环就好  我却写了个BFS

[code]:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;
typedef long long LL;
typedef pair<int,int> PII;

double dp[505][505];
int r,b;
bool vis[505][505];
queue<PII> Q;

void bfs(){
    int i,j,x,y;
    while(!Q.empty()) Q.pop();
    dp[0][1] = 1;
    Q.push(PII(0,1));
    vis[0][1] = 1;
    while(!Q.empty()){
        PII p = Q.front();Q.pop();
        x = p.first,y = p.second;
        vis[x][y] = 0;
        if((x+y)&1){
            if(y+1>=505) continue;
            dp[x][y+1] += dp[x][y];
            if(!vis[x][y+1]){
                vis[x][y+1] = 1;
                Q.push(PII(x,y+1));
            }
        }else{
            if(x+1<505){
                dp[x+1][y] += 1.0*(x+1)*dp[x][y]/(x+y+1);
                if(!vis[x+1][y]){
                    vis[x+1][y] = 1;
                    Q.push(PII(x+1,y));
                }
            }
            if(y+1<505){
                dp[x][y+1] += 1.0*(y+1)*dp[x][y]/(x+y+1);
                if(!vis[x][y+1]){
                    vis[x][y+1] = 1;
                    Q.push(PII(x,y+1));
                }
            }
        }
    }
}

int main(){
    int i,j,k,cas,T;
    bfs();
    scanf("%d",&cas);
    for(T = 1;T <= cas;T++){
        scanf("%d%d",&r,&b);
        printf("Case %d: %.8f\n",T,dp[r][b]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值