CF148Bag of mice
题意&思路:
有w只白鼠和b只黑鼠,公主和龙轮流从袋子中抓老鼠,抓到白鼠的获胜。龙在抓老鼠的时候,有一只老鼠会逃跑。公主先手,问公主胜利的概率。
第一次公主要获胜的概率是:
w
w
+
b
\frac{w}{w+b}
w+bw。
如果第一次公主没有抓到白鼠,那么公主想要获胜则需要龙也抓到黑鼠,所以概率是:
b
w
+
b
∗
b
−
1
w
+
b
−
1
\frac{b}{w+b}*\frac{b-1}{w+b-1}
w+bb∗w+b−1b−1。
那么逃跑的老鼠如果是白色的概率:
w
w
+
b
−
2
\frac{w}{w+b-2}
w+b−2w;黑色的概率为:
b
−
2
w
+
b
−
2
\frac{b-2}{w+b-2}
w+b−2b−2。
第二次针对上述的两种情况,公主第二次获胜的概率分别是:
w
−
1
w
+
b
−
3
\frac{w-1}{w+b-3}
w+b−3w−1 或者
w
w
+
b
−
3
\frac{w}{w+b-3}
w+b−3w。
由此,我们可以设在
i
i
i只白鼠,
j
j
j只黑鼠的时候,公主胜率为
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]。
某次赢得概率为:
d
p
[
i
]
[
j
]
=
i
i
+
j
dp[i][j]=\frac{i}{i+j}
dp[i][j]=i+ji。
此次如果公主和龙都没抓到白鼠,跑掉一只老鼠过后过后有两种状态分别是
d
p
[
i
−
1
]
[
j
−
2
]
dp[i-1][j-2]
dp[i−1][j−2]和
d
p
[
i
]
[
j
−
3
]
dp[i][j-3]
dp[i][j−3]。
所以可以得到:
d
p
[
i
]
[
j
]
=
i
i
+
j
+
j
i
+
j
∗
j
−
1
i
+
j
−
1
∗
(
i
i
+
j
−
2
∗
d
p
[
i
−
1
]
[
j
−
2
]
+
j
−
2
i
+
j
−
2
∗
d
p
[
i
]
[
j
−
3
]
)
\begin{aligned}dp[i][j]=\frac{i}{i+j}+\frac{j}{i+j}*\frac{j-1}{i+j-1}*(\frac{i}{i+j-2}*dp[i-1][j-2]+\frac{j-2}{i+j-2}*dp[i][j-3])\end{aligned}
dp[i][j]=i+ji+i+jj∗i+j−1j−1∗(i+j−2i∗dp[i−1][j−2]+i+j−2j−2∗dp[i][j−3])
再需要判断一下边界的条件,即
j
>
=
2
j>=2
j>=2和
j
>
=
3
j>=3
j>=3的时候。
最后输出
d
p
[
w
]
[
b
]
dp[w][b]
dp[w][b]就行了。
代码:
#include<bits/stdc++.h>
const int N=1e6+10;
const int mod=1e7+9;
const int maxn=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
const int inf=99999999;
using namespace std;
double dp[1010][1010];
int main()
{
int w,b;
scanf("%d%d",&w,&b);
int i,j;
for(i=1;i<=w;i++) dp[i][0]=1;
for(i=1;i<=b;i++) dp[0][i]=0;
for(i=1;i<=w;i++)
for(j=1;j<=b;j++)
{
dp[i][j]=i*1.0/(i+j);
if(j>=2)
{
double k=(j*1.0/(i+j))*((j-1)*1.0/(i+j-1));
dp[i][j]+=k*(i*1.0/(i+j-2)*dp[i-1][j-2]);
if(j>=3)
dp[i][j]+=k*((j-2)*1.0/(i+j-2)*dp[i][j-3]);
}
}
printf("%.9lf\n",dp[w][b]);
return 0;
}