【概率與期望】AGC019 F Yes or No
阿新 • • 發佈:2018-11-07
分析:
首先,很容易搞出來一個N^2的DP做法,顯然會T,但是對發現正解有很大幫助:
將這個DP轉換為一個網格,就變為:從起始點(n,m)出發,到達目標點(0,0)的期望路徑長度。
首先,有一個很厲害的結論:因為每次都是按照最優策略選答案,所以不妨設n>=m,那麼一定能答對n次。證明很顯然,每次當n>m時我們都會n的那一項,儘管答案可能會錯,但錯了之後,n會更大,我們更會選n。直到最終沒有m了,或者終於答對一次,n減少1。
有了這個結論以及其證明的過程,顯然不在對角線(i,i)上的點已經不用考慮了。其選擇方案之和永遠為n。
顯然,在對角線上的點,我們只能隨便選一個答案,無論選哪個都將離開對角線,並且期望得分都為1/2。
因此,我們可以爆枚每個對角線上的點被選中的概率,把它乘以1/2累加起來即可。
最後把累加的和加上n就做完了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define SF scanf
#define PF printf
#define MAXN 1000010
#define MOD 998244353
using namespace std;
typedef long long ll;
ll fac[MAXN],ifac[MAXN];
ll ans;
ll fsp(ll x,int y) {
ll res=1;
while(y){
if(y&1)
res=res*x%MOD;
x=x*x%MOD;
y>>=1;
}
return res;
}
void prepare(){
fac[0]=1;
for(int i=1;i<=1000000;i++)
fac[i]=fac[i-1]*i%MOD;
ifac[1000000]=fsp(fac[1000000],MOD-2);
for(int i=1000000;i>=1;i--)
ifac[i-1]=ifac[i]*i%MOD;
}
ll C(int n,int m){
return fac[n]*ifac[ m]%MOD*ifac[n-m]%MOD;
}
int main(){
int n,m;
prepare();
SF("%d%d",&n,&m);
if(n<m)
swap(n,m);
for(int i=1;i<=m;i++)
ans=(ans+C(2*i,i)*C(n+m-2*i,n-i)%MOD)%MOD;
ans=ans*fsp(2ll*C(n+m,n)%MOD,MOD-2)%MOD;
ans=(ans+n)%MOD;
PF("%lld",ans);
}