AGC019 F- Yes or No 题解

    科技2022-08-02  106

    题目传送门

    题目大意: 有 n + m n+m n+m 道判断题,有 n n n 道的答案为正确,有 m m m 道的答案为错误,进行 n + m n+m n+m 轮提问,每次随机给你一道题,你不知道它的答案,但是你回答后他会告诉你是否答对了,问你在最优策略下期望能答对多少题。

    题解

    显然最优策略是每次答剩余题数较多的那类题,一顿找规律后不难发现一定能答对 max ⁡ ( n , m ) \max(n,m) max(n,m) 道题。

    证明的话,不妨令 n > m n>m n>m,那么此时肯定回答正确,假如答案正确,那么 a n s + 1 , n − 1 ans+1,n-1 ans+1,n1,否则 a n s ans ans 不变, m − 1 m-1 m1,此时 n n n 是不变的,依然满足 n > m n>m n>m,也就是说,让 n n n 减小的唯一条件是答对了,即只有答对了能让较大的数减小,所以肯定能答对 max ⁡ ( n , m ) \max(n,m) max(n,m) 道。

    但是还有一个需要计算的地方,如果操作过程中,出现了 n = m n=m n=m,那么此时无论答对还是答错,后继状态都是 n , n − 1 n,n-1 n,n1(可能是 n n n 道正确 + + + m m m 道错误,也可能反过来,但都是一样的),即这一步无论是否答对,后面依然能答对 n n n 个,也就是说,这一步如果答对了,那么会在 max ⁡ ( n , m ) \max(n,m) max(n,m) 的基础上额外多对 1 1 1 道。

    于是对于每个 ( i , i ) (i,i) (i,i),统计出有多少条路径经过它,设为 d d d,那么他提供的额外期望值就是 d / 2 d/2 d/2

    代码如下:

    #include <cstdio> #include <algorithm> using namespace std; #define maxn 1000010 #define mod 998244353 int n,m; int fac[maxn],inv[maxn],inv_fac[maxn]; void FacInit(int N){ fac[0]=inv_fac[0]=inv[1]=1; for(int i=1;i<=N;i++)fac[i]=1ll*fac[i-1]*i%mod; for(int i=2;i<=N;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod; for(int i=1;i<=N;i++)inv_fac[i]=1ll*inv_fac[i-1]*inv[i]%mod; } int Binom(int x,int y){return 1ll*fac[x]*inv_fac[y]%mod*inv_fac[x-y]%mod;} void add(int &x,int y){x=(x+y>=mod?x+y-mod:x+y);} int ksm(int x,int y){int re=1;for(;(y&1?re=1ll*re*x%mod:0),y;y>>=1,x=1ll*x*x%mod);return re;} int main() { scanf("%d %d",&n,&m);FacInit(n+m); if(n<m)swap(n,m);int ans=0; for(int i=1;i<=m;i++)add(ans,1ll*Binom(n-i+m-i,n-i)*Binom(i+i,i)%mod); ans=1ll*ans*ksm(2ll*Binom(n+m,n)%mod,mod-2)%mod;add(ans,n); printf("%d",ans); }
    Processed: 0.009, SQL: 8