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

原文地址:https://www.cnblogs.com/1024-xzx/p/13492271.html