AGC019F Yes or No

17 篇文章 0 订阅

题意

有N+M个问题,其中N个答案是YES,M个是NO
每次你可以回答YES或NO,问答对个数的期望
当然还有个条件,当你回答了某个问题后,你会得知这道题的正确答案。所以问你采取最优方案时的期望

题解

我们转化成路径问题,变成某个点从(0,0)走到(n,m),它会随机的往右或上走,然后每一步之前我们来猜它会往哪边走
那么假如我们在过程中不会知道它走到了哪里,我们就肯定是猜测它往右走(不妨设N>=M),那么我们期望的猜对次数就是N
那回到原来的问题。显然,如果我们当前所剩下的向右走的机会大于向上走的机会,我们还是会猜测向右走的
当我们穿过对角线的时候,就又成了一个子问题,而且可以发现,所有的不在对角线的的贡献加起来就是N(N>=M)
那么…就是算对角线的贡献了
其实就是对每一个对角线上的点,算一下它在路径上的概率,再乘上1/2就好了,这是一个比较基本的组合数学问题。
以上。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1000005;
const int mod=998244353;
const int inv2=499122177;
int fact[N+5],inv[N+5];
void Init(){
    fact[0]=1;
    for(int i=1;i<=N;i++)
        fact[i]=1ll*fact[i-1]*i%mod;
    inv[1]=1;
    for(int i=2;i<=N;i++)
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    inv[0]=1;
    for(int i=1;i<=N;i++)
        inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
int C(int x,int y){
    if(x<y)
        return 0;
    return 1ll*fact[x]*inv[y]%mod*inv[x-y]%mod;
}
int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)
            res=1ll*res*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return res;
}
int main()
{
    Init();
    int n,m;
    scanf("%d%d",&n,&m);
    if(n<m)
        swap(n,m);
    int ans=0;
    for(int i=1;i<=m;i++){
        ans=(ans+1ll*C(i+i,i)*C(n+m-2*i,m-i)%mod)%mod;
    }
    ans=1ll*ans*ksm(C(n+m,n),mod-2)%mod*inv2%mod;
    ans=(ans+n)%mod;
    printf("%d\n",ans);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值