• 「ABC231 G」 Balls in Boxes 题解


    「ABC231 G」 Balls in Boxes 题解

    \(~~~~\) 终于有一道题让我有动力起魔怔标题了。

    题意

    \(~~~~\) \(n\) 个盒子,初始第 \(i\) 个盒子有 \(a_i\) 个球,将 \(k\) 个球依次独立随机放入 \(n\) 个盒子内。定义最终状态的权值为所有盒子内球数量的积,求期望权值。

    \(~~~~\) \(1\leq n\leq 1000,1\leq k\leq 10^9\)

    题解

    \(~~~~\) 期望很假,由于放球共有 \(n^k\) 种情况这很好求,所以问题在于 \(n^k\) 种情况的权值和。

    \(~~~~\) 假设所有 \(a_i=0\) 怎么做,记 \(x_{i,j}\in\{0,1\}\) 表示第 \(i\) 个盒子内是否放了球 \(j\),那贡献就可以表示为:

    \[\large \prod_{i=1}^n (\sum_{j=1}^k x_{i,j}) \]

    \(~~~~\) 展开的话就会是若干形似这样的项之和:

    \[\large \prod_{i=1}^n x_{i,t_i}~~~~(t_i\in [1,n]) \]

    \(~~~~\) 显然当所有 \(x\) 都取 \(1\) 时其才会产生贡献,更进一步这里取到的 \(t_i\) 应该互不相同。那合法的 \(\{t_i\}\) 就应该

    \(~~~~\) 那考虑对于已经合法的 \(\{t_i\}\) ,其他球就可以乱放了,所以每组 \(\{t_i\}\) 对应 \(n^{k-n}\) 种方案,每种的贡献为 \(1\)

    \(~~~~\) 所以最后的答案就是 \(\dfrac{k!}{(k-n)!}\times n^{k-n}\) ,然后除上总方案数就是期望。

    \(~~~~\) 现在加上初始值,那我们认为每个盒子的增量\(b_i\) ,依然很好求总方案,那要求的最后的总权值期望是:

    \[\large \sum_{\{b_i\}} (\prod_{i=1}^n(a_i+b_i)) \]

    \(~~~~\) 把里面拆开可以发现总是由 \(x\)\(a\) 的积和 \(n-x\)\(b\) 的积做乘法,然后加和。

    \(~~~~\) 那就预处理出所有由 \(x\)\(a\) 相乘得到的数之和 \(\text {and}\) 所有 \(n-x\)\(b\) 相乘的得到的数之和,其中 \(a\) 这部分记为 \(f\) ,可以有 DP:定义 \(f_{i,j}\) 表示前 \(i\) 个数中所有选 \(j\) 个情况的积的和,转移方程:\(f_{i,j}=f_{i-1,j}+f_{i-1,j-1}\times a_i\) 。而求 \(g\) 的话只需要类比上面就可以了,答案是 \(\dfrac{k!}{(k-i)!}\times n^{k-i}\)

    \(~~~~\) 那最后的答案由 \(f\)\(g\) 卷一下就可以得到:

    \[\large \sum_{i=0}^n f_i\times g_{n-i} \]

    \(~~~~\) 然后再除以方案数就是期望了。

    代码

    查看代码
    #include <cstdio>
    #include <algorithm>
    #define ll long long
    using namespace std;
    const int MOD=998244353;
    int n,k;
    int arr[1005],dp[1005][1005],f[1005],g[1005];
    ll qpow(ll a,ll b)
    {
    	ll ret=1;
    	while(b)
    	{
    		if(b&1) ret=ret*a%MOD;
    		b>>=1;a=a*a%MOD;
    	}
    	return ret;
    }
    int Get(int x)
    {
    	int ret=1;
    	for(int i=k;i>=k-x+1;i--) ret=1ll*ret*i%MOD;
    	return ret;
    }
    int main() {
    	scanf("%d %d",&n,&k);
    	dp[0][0]=1;
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&arr[i]);
    		for(int j=0;j<=n;j++)
    			dp[i][j]=(dp[i-1][j]+(j>=1?1ll*dp[i-1][j-1]*arr[i]%MOD:0))%MOD;
    		if(i==n) for(int j=0;j<=n;j++) f[j]=dp[i][j];
    	}
    	int Up=min(n,k);
    	for(int i=0;i<=Up;i++) 
    		g[i]=1ll*Get(i)*qpow(n,k-i)%MOD;
    	int Ans=0;
    	for(int i=0;i<=n;i++) Ans=(1ll*Ans+1ll*f[i]*g[n-i]%MOD)%MOD;
    	printf("%lld",1ll*Ans*qpow(qpow(n,k),MOD-2)%MOD);
    	return 0;
    }
    
  • 相关阅读:
    9.12 其他样式;JS
    9.11 样式表
    9.9 样式表
    PHP延迟几秒后执行,PHP延迟执行,PHP停顿几毫秒后执行 usleep() 和 sleep()
    PHP 去除url参数中出现+、空格、=、%、&、#等字符的解决办法, PHP去除影响url路径的字符
    java第一堂课-常用的电脑快捷键操作和重要的dos命令
    常用第三方接口,支付宝支付,微信支付,软著,IOS开发者账号
    苹果开发者账号申请流程完整版 https://www.jianshu.com/p/655380201685
    thinkphp 去重查询
    将数据导【入】【excel表】格式 前端页面
  • 原文地址:https://www.cnblogs.com/Azazel/p/16128080.html
Copyright © 2020-2023  润新知