• Battle for Wosneth2【概率】-2020百度之星复赛


    题意

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6842

    分析

    考虑一个二维的 (DP) 模型,每次对连续两轮进行分析。如果两个人都没有打中对方,没有意义。而且最终二者的状态一定是 ((r,1)),然后 (Alice) 一枪把 (Bob) 干掉。所以对于 ((i,j)),有三种后继状态:

    • ((i-1,j-1)),转移的概率为 (a=frac{pq}{1-(1-p)(1-q)})
    • ((i,j-1)),转移的概率为 (b=frac{p(1-q)}{1-(1-p)(1-q)})
    • ((i-1,j)),转移的概率为 (c=frac{(1-p)q}{1-(1-p)(1-q)})

    最后,(Alice) 一枪打死 (Bob) 的概率为 (d=frac{p}{1-(1-p)(1-q)})

    我们先计算出 ((n,m) o (r,1)) 的概率,然后再计算 ((r,1) o (r,0)) 的概率。

    下面对上述的三种转移方式的次数进行讨论,假设第一种方式的次数为 (x),那么第二种方式的次数为 (m-1-x),第三种方式的次数为 (n-r-x)。令 (i=n-r),则概率如下:

    [egin{align} P & = sum_{i=0}^{n-1}{sum_{x=0}^{min(m-1,i)}{C(m-1+i-x,i-x)·C(m-1,x)·a^x·b^{m-1-x}·c^{i-x}}} end{align} ]

    此时,无法直接处理,考虑改变枚举顺序,同时令第三种方式的次数为 (i),有:

    [egin{align} P & = sum_{x=0}^{min(n-1,m-1)}{C(m-1,x)·a^x·b^{m-1-x}sum_{i=0}^{n-1-x}{C(m-1-i,i)·c^i}} end{align} ]

    (S(r)=sum_{i=0}^{r}{C(m-1-i,i)·c^i}),可以预处理。最终答案为:

    [egin{align} P & =d· sum_{x=0}^{min(n-1,m-1)}{C(m-1,x)·a^x·b^{m-1-x}·S(n-1-x)} end{align} ]

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int N=1e5+5;
    const int mod=998244353;
    const int inv100=828542813;
    ll sum[N],fac[N<<1],inv[N];
    int n,m;
    ll p,q,a,b,c,d;
    ll power(ll x,ll y)
    {
        ll res=1;
        x%=mod;
        while(y)
        {
            if(y&1) res=res*x%mod;
            x=x*x%mod;
            y>>=1;
        }
        return res;
    }
    void init()
    {
        int maxn=1e5,up=2e5;
        fac[0]=1;
        for(int i=1;i<=up;i++)
            fac[i]=fac[i-1]*i%mod;
        inv[maxn]=power(fac[maxn],mod-2);
        for(int i=maxn-1;i>=0;i--)
            inv[i]=inv[i+1]*(i+1)%mod;
    }
    ll solve()
    {
        //预处理sum
        sum[0]=1;
        ll tc=1;
        for(int i=1;i<n;i++)
        {
            tc=tc*c%mod;
            ll ci=fac[m-1+i]*inv[i]%mod*inv[m-1]%mod;
            sum[i]=(sum[i-1]+ci*tc%mod)%mod;
        }
        int minn=min(n-1,m-1);
        ll ta=1,tb=power(b,m-1);
        ll ans=tb*sum[n-1]%mod;
        ll ib=power(b,mod-2);
        for(int i=1;i<=minn;i++)
        {
            ta=ta*a%mod;
            tb=tb*ib%mod;
            if(i==m-1&&b==0) tb=1;//注意
            ll ci=fac[m-1]*inv[m-1-i]%mod*inv[i]%mod;
            ans=(ans+ci*ta%mod*tb%mod*sum[n-1-i]%mod)%mod;
        }
        return ans;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        init();
        while(T--)
        {
            scanf("%d%d%lld%lld",&n,&m,&p,&q);
            p=p*inv100%mod;
            q=q*inv100%mod;
            ll t=power(1-(1-p)*(1-q)%mod+mod,mod-2);
            a=p*q%mod*t%mod;
            b=(p*(1-q)%mod*t%mod+mod)%mod;
            c=((1-p)*q%mod*t%mod+mod)%mod;
            d=p*t%mod;
            ll ans=d*solve()%mod;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
    
    

    参考博客:https://www.cnblogs.com/Lanly/p/13473041.html#e-battle-for-wosneth2-hdu-6842

  • 相关阅读:
    Anaconda和Miniconda的安装
    并联谐振电路频率阻抗及计算曲线带宽案例摘要
    TEM波
    Android Studio实现简单考试应用程序
    android studio实现简单考试应用程序
    Android Studio的简易计算器界面设计
    时谐变换
    简要理解什么是趋肤效应
    c盘清理
    如何把Visual Studio完全安装在其他磁盘
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/13492271.html
Copyright © 2020-2023  润新知