题目:
https://www.luogu.com.cn/problem/CF148D
袋子里有 n n n只白鼠和 m m m只黑鼠 , A A A和 B B B轮流从袋子里抓,谁先抓到白色谁就赢。 A A A每次随机抓一只, B B B每次随机抓完一只之后会有另一只随机老鼠跑出来。如果两个人都没有抓到白色则 B B B赢。 A A A先抓,问 A A A赢的概率。
思路:
三元组
(
A
,
i
,
j
)
(A,i,j)
(A,i,j)表示有
i
i
i只白鼠,
j
j
j只黑鼠,
A
A
A先抓这种状态
用
f
(
A
,
i
,
j
)
f(A,i,j)
f(A,i,j)表示以
(
A
,
i
,
j
)
(A,i,j)
(A,i,j)表示的状态开始游戏,
A
A
A赢的概率,答案为
f
(
A
,
n
,
m
)
f(A,n,m)
f(A,n,m)。
(
A
,
i
,
j
)
i
i
+
j
→
A
赢
(
A
,
i
,
j
)
j
i
+
j
→
(
B
,
i
,
j
−
1
)
\begin{aligned} &(A,i,j)\quad\frac{i}{i+j}\rightarrow\quad A赢\\ &(A,i,j)\quad\frac{j}{i+j}\rightarrow\quad (B,i,j-1)\\ \end{aligned}
(A,i,j)i+ji→A赢(A,i,j)i+jj→(B,i,j−1)
表示
(
A
,
i
,
j
)
(A,i,j)
(A,i,j)有
i
i
+
j
\frac{i}{i+j}
i+ji 的概率直接进入赢得状态,
j
i
+
j
\frac{j}{i+j}
i+jj的概率进入
(
B
,
i
,
j
−
1
)
(B,i,j-1)
(B,i,j−1)这种状态。所以有
f
(
A
,
i
,
j
)
=
i
i
+
j
∗
1
+
j
i
+
j
∗
f
(
B
,
i
,
j
−
1
)
f(A,i,j)=\frac{i}{i+j}*1+\frac{j}{i+j}*f(B,i,j-1)
f(A,i,j)=i+ji∗1+i+jj∗f(B,i,j−1)
同理分析
(
B
,
i
,
j
)
(B,i,j)
(B,i,j)。
可以直接记忆化搜索,注意初始值的分析。
#include<bits/stdc++.h>
using namespace std;
const int N=1009;
int n,m;
double dp[2][N][N];
double dfs(int x,int y,int z)
{
if(!y)
return 0;
if(!z&&x)
return 1;
if(!z)
return 0;
if(z<0&&x)
return 0;
if(dp[x][y][z]!=0)
return dp[x][y][z];
if(x)
dp[x][y][z]+=(double)z/(y+z)*dfs(0,y,z-1)+(double)y/(y+z);
else
dp[x][y][z]+=(double)z/(y+z)*(((double)z-1)/(y+z-1)*dfs(1,y,z-2)+(double)y/(y+z-1)*dfs(1,y-1,z-1));
return dp[x][y][z];
}
int main()
{
scanf("%d%d",&n,&m);
printf("%.9lf",dfs(1,n,m));
return 0;
}