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 <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;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值