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)\to (r,1)\) 的概率,然后再计算 \((r,1)\to (r,0)\) 的概率。

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

\[\begin{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\),有:

\[\begin{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}\),可以预处理。最终答案为:

\[\begin{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\n",ans);
    }
    return 0;
}


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

posted @ 2020-08-12 21:45  xzx9  阅读(240)  评论(0)    收藏  举报