UOJ #390 - 【UNR #3】百鸽笼

考虑转化模型(有点类似于 PKUSC2018 猎人杀):生成一个值域为 [1,n] 的无穷序列,记 bi 表示其中第 aii 的位置,那么所求即为 bib 序列中的最大值的概率。

容斥。假设我们要计算 x 的答案,我们考虑钦定一个集合 S 满足 S 中的所有元素的 b 都大于 bx(即在第 axx 前的出现次数 <bx),那么我们考虑 dpi,j,k 表示考虑到前 i 个数,钦定了 j 个数,它们总出现次数为 k 的方案数,转移是 O(n) 的,最后计算答案的时候发现贡献系数只取决于 jk,因为其实不在 S 中的数我们可以忽略不计,相当于每个数生成的概率为 1j+1,所以一对 j,k 的贡献系数就是 (1)j·(1j+1)k+ax

时间复杂度 O(n6),可以优化到 O(n5),但是直接实现就可以通过。

const int MAXN=30;
const int MAXS=900;
const int MOD=998244353;
int qpow(int x,int e){int ret=1;for(;e;e>>=1,x=1ll*x*x%MOD)if(e&1)ret=1ll*ret*x%MOD;return ret;}
int n,a[MAXN+5],c[MAXS+5][MAXS+5],pw[MAXN+5][MAXS+5];
int main(){
scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=0;i<=MAXS;i++){
c[i][0]=1;
for(int j=1;j<=i;j++)c[i][j]=(c[i-1][j]+c[i-1][j-1])%MOD;
}
for(int i=1;i<=n;i++){
int iv=qpow(i,MOD-2);
for(int j=(pw[i][0]=1);j<=MAXS;j++)pw[i][j]=1ll*pw[i][j-1]*iv%MOD;
}
for(int t=1;t<=n;t++){
static int dp[MAXN+5][MAXS+5];int sum=0,res=0;
memset(dp,0,sizeof(dp));dp[0][0]=1;
for(int i=1;i<=n;i++){
if(i==t)continue;
for(int j=i-1;~j;j--)for(int k=0;k<=sum;k++)if(dp[j][k]){
for(int l=0;l<a[i];l++)
dp[j+1][k+l]=(dp[j+1][k+l]+1ll*dp[j][k]*c[k+l][l])%MOD;
}
sum+=a[i];
}
for(int i=0;i<n;i++)for(int j=0;j<=sum;j++)if(dp[i][j]){
int coef=1ll*dp[i][j]*c[j+a[t]-1][a[t]-1]%MOD*((i&1)?(MOD-1):1)%MOD*pw[i+1][j+a[t]]%MOD;
res=(res+coef)%MOD;
}printf("%d ",res);
}
return 0;
}
posted @   tzc_wk  阅读(58)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
历史上的今天:
2022-07-14 Codeforces 720F - Array Covering(wqs 二分+线段树优化 dp)
2022-07-14 Codeforces 1439D - INOI Final Contests(DP)
点击右上角即可分享
微信分享提示