题目链接
https://codeforces.com/gym/102190
题解思路
设
d
p
[
i
]
[
0
]
dp[i][0]
dp[i][0]表示乌龟在对面,两边各有一张的牌共
i
i
i张 先手赢的概率
设
d
p
[
i
]
[
1
]
dp[i][1]
dp[i][1]表示乌龟在自己,两边各有一张的牌共
i
i
i张 先手赢的概率
乌龟在对面有两种转移方式,分别是抽对面乌龟和抽对面正常牌
乌龟在自己有一种转移方式,抽对面正常牌
我先走转移到下一个状态就是对面先走,dp方程表示的是我赢的概率,到下一个状态就是对手输
转移方程如下:
d
p
[
i
]
[
0
]
=
i
i
+
1
∗
(
1
−
d
p
[
i
−
1
]
[
1
]
)
+
1
i
+
1
∗
(
1
−
d
p
[
i
]
[
0
]
)
dp[i][0]=\frac{i}{i+1}*(1-dp[i-1][1])+\frac{1}{i+1}*(1-dp[i][0])
dp[i][0]=i+1i∗(1−dp[i−1][1])+i+11∗(1−dp[i][0])
d
p
[
i
]
[
1
]
=
1
−
d
p
[
i
−
1
]
[
0
]
dp[i][1]=1-dp[i-1][0]
dp[i][1]=1−dp[i−1][0]
另外 d p [ i ] [ 0 ] dp[i][0] dp[i][0]和 d p [ i ] [ 1 ] dp[i][1] dp[i][1]在数值上没关系,正常转移就行
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define debug cout<<"fuck"<<endl;
#define pb push_back
#define endl '\n'
const int mod=(int)1e9+7;
const int maxn=(int)1e6+5;
string s1,s2;
int t,n;
//0表示乌龟在对面,1表示乌龟在自己
double dp[maxn][2];
void init()
{
dp[0][0]=1.0,dp[0][1]=0.0;
for(int i=1;i<maxn;i++)
{
dp[i][0]=(1+i*(1-dp[i-1][1]))/(i+2);
dp[i][1]=1-dp[i-1][0];
}
}
signed main()
{
init();
//cout<<dp[5][1]<<' '<<dp[5][0]<<endl;
IOS
cin>>t;
while(t--)
{
cin>>n;
cin>>s1>>s2;
int num=0;
int fl=0;
for(int i=0;i<n;i++)
{
if(s1[i]=='1'&&s2[i]=='1')
{
num++;
}
if(s1[i]=='1'&&s2[i]=='0')
{
fl=1;
}
}
cout<<fixed<<setprecision(10)<<dp[num][fl]<<endl;
}
return 0;
}