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 + ;
double f[maxn][maxn][];
bool arrive[maxn][maxn][]; double dp(int i,int j,int k)
{
if (arrive[i][j][k])
return f[i][j][k];
double & ans = f[i][j][k] = .;
arrive[i][j][k] = true;
if (i == && j == )
return ans = .;
if (j == )
{
if (k == && i >= )
return ans = 1.0;
else if(k == && i >=)
return ans = .;
else if (k == && i >= )
return ans = 1.0;
return ans = 0.0;
}
if (i == )
return ans = .;
int next = (k+) % ;
if (k == )
ans = (double)i / (double)(i+j) + dp(i,j-,next) * ((double)j/(double)(i+j));
else if (k == )
ans = dp(i,j-,next) * ((double)j/(i+j));
else
ans = dp(i-,j,next) * ( (double)i / (double)(i+j) ) + dp(i,j-,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,));
return ;
}