AtCoder Grand Contest 019 F Yes or No

Yes or No

Description

n + m 个问题,其中 n 个问题的答案为 Yes m 个问题的答案为 No ,现在题目以某种顺序依次给出,每次需要回答 Yes No ,在回答完一个问题后你可以马上知道这个问题的正确答案,问期望最多能答对多少题。

Data Constraint

n,m <= 105

Solution

n >= m
可以把答案看成一条由( 0 , 0 )走到( n , m )的路径(每次只能向右或向上走)。
画出直线 y = x - n + m
可以发现当你走到直线上方的决策点时,回答 Yes 答对的概率更大,当你走到直线下方的决策点时,回答 No 答对的概率更大,即不在直线上的决策点时,决策一定(每次回答正确概率更大的答案),且不难发现,无论如何决策一定的决策点一共会有 n 的贡献。

剩下的便是直线上的决策点的贡献,将有 12 的概率答对,对于每个直线上的决策点算出走到该决策点的概率再乘上 12 便是对答案的贡献了。

Code

#include
#include
#include
#include

#define fo(i,j,l) for(int i=j;i<=l;++i)
#define fd(i,j,l) for(int i=j;i>=l;--i)

using namespace std;
typedef long long ll;
const ll N=12e5,mo=998244353;

ll jc[N],ny[N];
int n,m,k;

inline ll ksm(ll o,ll t)
{
    ll y=1;
    for(;t;t>>=1,o=o*o%mo)
    if(t&1)y=y*o%mo;
    return y;
}

inline ll C(ll a,ll b)
{return jc[a]*ny[b]%mo*ny[a-b]%mo;}

int main()
{
    cin>>n>>m;
    if(n<m)swap(n,m);
    k=n<<1;
    jc[0]=ny[0]=1;
    fo(i,1,k)jc[i]=jc[i-1]*i%mo;
    ny[k]=ksm(jc[k],mo-2);
    fd(i,k-1,1)ny[i]=ny[i+1]*(i+1)%mo;
    ll ans=0;
    for(int h=0,z=n-m;h<m;++h,++z)
    ans=(ans+C(h+z,z)*C(n+m-h-z,m-h))%mo;
    ans=ans*ny[2]%mo;
    ll zg=C(n+m,m);
    ans=ans*ksm(zg,mo-2)%mo;
    ans=(ans+n)%mo;
    cout<

你可能感兴趣的:(数学)