题意: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;
}