noip模拟试题:赌神

时间:2021-09-13
本文章向大家介绍noip模拟试题:赌神,主要包括noip模拟试题:赌神使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

理解后感觉是一道很好的题,虽然考场上连题都没怎么看懂
先考虑 \(n=2\) 的情况,令 \(dp_{i,j}\) 表示剩 \(i\) 个1号球和 \(j\) 个2号球答案乘上的系数
则此时设两个球我们分别压得筹码为 \(k_1\)\(k_2\),则我们有
\( dp_{i,j}=min\left \{ nk_1*dp_{i-1,j} , nk_2*dp_{i,j-1} \right \} \)
可以证明全压一定不比不压劣
那我们就有 \(k_1+k_2=1->k_1=1-k_2\)
带入上面式子,得 \(dp_{i,j}=min\left \{ n(1-k_2)*dp_{i-1,j} , nk_2*dp_{i,j-1} \right \}\)
及对两个一次函数取 \(min\) ,当两式相等时, \(dp_{i,j}\)\(max\)
移项得 \(dp_{i,j}=2*\frac{dp_{i-1,j}dp_{i,j-1}}{dp_{i-1,j}+dp_{i,j-1}}\)
接下来题解的思路很巧妙
\(f_{i,j}=\frac{dp_{i,j}}{2^{i+j}}\)
则根据我们刚才得到的式子得到 \(\frac{1}{f_{i,j}}=\frac{1}{f_{i-1,j}}+\frac{1}{f_{i,j-1}}\),转换到二维平面,我们令 \(f_{0,0}=1\) 后,其实就是求走法的方案数
推广到 \(n\) 维,结论相同,求 \(n\) 维走法的方案数就好了

Code
#include <bits/stdc++.h>
#define re register
#define db double
#define int long long
#define pir make_pair
using namespace std;
const int maxn=1e6+5;
const int INF=1e9+10;
const int mol=998244353;
inline int read(){
    int x=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9') w=(ch=='-')?-1:1,ch=getchar();
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*w;
}

int n,tot,num[maxn],fac[maxn],inv[maxn];
inline int qpow(int a,int b) { int ans=1; while(b) { if(b&1) (ans*=a)%=mol; (a*=a)%=mol; b>>=1; } return ans; }
inline int C(int n,int m) { return fac[n]*inv[n-m]%mol*inv[m]%mol; }
signed main(void) {
    n=read(); for(re int i=1;i<=n;i++) num[i]=read(),tot+=num[i];
    fac[0]=1;
    for(re int i=1;i<=tot;i++) fac[i]=fac[i-1]*i%mol;
    inv[tot]=qpow(fac[tot],mol-2);
    for(re int i=tot;i>=1;i--) inv[i-1]=inv[i]*i%mol;
    int ans=qpow(n,tot);
    for(re int i=1;i<n;i++) {
        (ans*=qpow(C(tot,num[i]),mol-2))%=mol;
        tot-=num[i];
    }
    printf("%lld\n",ans);
}

原文地址:https://www.cnblogs.com/zjxlm/p/15263253.html