题面:
思路:
手推好像样例也算不出来,然后观察它的样子,发现可以考虑dp
f[i][j]为有i个红球,j个黑球的时候,先手获胜的概率
第一局先手直接获胜的概率:
i
i
+
j
{i \over i+j}
i+ji
第二局先手获胜的概率(即第一局,先手和后手摸到的都是黑球)
后手偷偷摸的是黑球:
j
i
+
j
⋅
j
−
1
i
+
j
−
1
⋅
j
−
2
i
+
j
−
2
⋅
f
[
i
]
[
j
−
3
]
{j \over i+j} \cdot {j-1 \over i+j-1} \cdot{j-2 \over i+j-2} \cdot f[i][j-3]
i+jj⋅i+j−1j−1⋅i+j−2j−2⋅f[i][j−3]
后手偷偷摸的是红球:
j
i
+
j
⋅
j
−
1
i
+
j
−
1
⋅
i
i
+
j
−
2
⋅
f
[
i
−
1
]
[
j
−
2
]
{j \over i+j} \cdot {j-1 \over i+j-1} \cdot {i \over i+j-2} \cdot f[i-1][j-2]
i+jj⋅i+j−1j−1⋅i+j−2i⋅f[i−1][j−2]
这样我们的递推式就可以找到了
f
[
i
]
[
j
]
=
i
i
+
j
+
j
i
+
j
⋅
j
−
1
i
+
j
−
1
⋅
j
−
2
i
+
j
−
2
⋅
f
[
i
]
[
j
−
3
]
+
j
i
+
j
⋅
j
−
1
i
+
j
−
1
⋅
i
i
+
j
−
2
⋅
f
[
i
−
1
]
[
j
−
2
]
f[i][j]={i \over i+j}+{j \over i+j} \cdot {j-1 \over i+j-1} \cdot{j-2 \over i+j-2} \cdot f[i][j-3]+{j \over i+j} \cdot {j-1 \over i+j-1} \cdot{i \over i+j-2} \cdot f[i-1][j-2]
f[i][j]=i+ji+i+jj⋅i+j−1j−1⋅i+j−2j−2⋅f[i][j−3]+i+jj⋅i+j−1j−1⋅i+j−2i⋅f[i−1][j−2]
然后要注意一下数据越界的问题
#include<bits/stdc++.h>
using namespace std;
const int maxn=1111;
double f[maxn][maxn];
int a,b;
int main( )
{
cin>>a>>b;
for (int i=1;i<=1000;i++) f[i][0]=1;
for (int i=1;i<=a;i++)
{
for (int j=1;j<=b;j++)
{
f[i][j]+=(double)i/(i+j);
if(j>=2)
{
f[i][j]+=((double)j/(i+j)*(j-1)/(i+j-1)*(double)i/(i+j-2)*f[i-1][j-2]);
if(j>=3) f[i][j]+=((double)j/(i+j)*(j-1)/(i+j-1)*(double)(j-2)/(i+j-2)*f[i][j-3]);
}
cout<<"i="<<i<<" "<<"j="<<j<<" "<<"f[i][j]=";
printf("%.12lf\n",f[i][j]);
}
}
printf("%.12lf\n",f[a][b]);
return 0;
}