F - 邱老师看电影
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
一天邱老师心血来潮想去看电影,但是邱老师的妹子想去逛街,他们谁也没有办法说服对方,于是准备来玩一个游戏来决定听谁的。
邱老师找来w只白鼠和b只黑鼠,邱老师和妹子轮流从袋子里面抓老鼠,谁先抓到白色老鼠谁就赢。
但是有酱神在旁边捣乱,邱老师每抓一只老鼠出来,酱神就偷偷的也从里面抓一只出来,这3个人抓出来的老鼠都是随机的。
如果袋子里没有白老鼠,且之前没有人拿到白老鼠的时候,邱老师胜。
为了体现绅士精神,邱老师让妹子先抓,那么妹子赢的概率是多少呐?
Input
只有两个数字 w和b w<=1000 b<=1000
Output
输出妹子赢的概率 保留9位小数
Sample input and output
Sample Input | Sample Output |
---|---|
1 3 | 0.500000000 |
解题报告:
f(i,j,k) -> i只白鼠,j只黑鼠,目前操作者是k号时妹纸赢的概率
0,妹
1,邱
2,酱
边界条件:
if (i == 0 && j == 0 )
return ans = 0;
if (j == 0)
{
if (k == 0 && i >= 1)
return ans = 1.0;
else if(k == 1 && i >=1)
return ans = 0.;
else if (k == 2 && i >= 2 )
return ans = 1.0;
return ans = 0.0;
}
if (i == 0)
return ans = 0.;
转移:
int next = (k + 1 ) % 3; //下一个操作的人
if (k == 0) // 妹纸操作
{
f(i,j,K) = ( i / (i+j) ) + dp(i,j-1, next) * ( j / (i+j) )
}
else if (k == 1) // 邱老师操作
{
f(i,j,k) = f(i,j-1,next) * (j / (i+j));
}
else // 酱老师操作
{
f(i,j,k) = f(i-1,j,next) * (i / (i+j) ) + f(i,j-1,next) * (j / (i+j))
}
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> using namespace std; const int maxn = 1e3 + 50; double f[maxn][maxn][3]; bool arrive[maxn][maxn][3]; double dp(int i,int j,int k) { if (arrive[i][j][k]) return f[i][j][k]; double & ans = f[i][j][k] = 0.; arrive[i][j][k] = true; if (i == 0 && j == 0) return ans = 0.; if (j == 0) { if (k == 0 && i >= 1) return ans = 1.0; else if(k == 1 && i >=1) return ans = 0.; else if (k == 2 && i >= 2 ) return ans = 1.0; return ans = 0.0; } if (i == 0) return ans = 0.; int next = (k+1) % 3; if (k == 0) ans = (double)i / (double)(i+j) + dp(i,j-1,next) * ((double)j/(double)(i+j)); else if (k == 1) ans = dp(i,j-1,next) * ((double)j/(i+j)); else ans = dp(i-1,j,next) * ( (double)i / (double)(i+j) ) + dp(i,j-1,next) * ( (double)j / (double)(i+j) ) ; return ans; } int main(int argc,char *argv[]) { int w,b; memset(arrive,false,sizeof(arrive)); scanf("%d%d",&w,&b); printf("%.9lf\n",dp(w,b,0)); return 0; }