ecnu个人赛 B Black Peter dp

题目链接

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(1dp[i1][1])+i+11(1dp[i][0])
d p [ i ] [ 1 ] = 1 − d p [ i − 1 ] [ 0 ] dp[i][1]=1-dp[i-1][0] dp[i][1]=1dp[i1][0]

另外 d p [ i ] [ 0 ] dp[i][0] dp[i][0] d p [ i ] [ 1 ] dp[i][1] dp[i][1]在数值上没关系,正常转移就行

#include 
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"<
#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<
    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;
}

你可能感兴趣的:(dp)