LG4707 重返现世[min-max 容斥][概率期望]

首先要有一些 kthmin-max 容斥的基本知识,不讲了。

求第 k 小,相应的转化成第 nk+1 大。

E(kthmax(S))=TS(1)|T|k(|T|1k1)E(min(T))=mTS(1)|T|k(|T|1k1)1iTai

注意到 m 在一个可接受的范围。

一个比较显然的想法是记 fi,j,d 表示前 i 个,和为 j,已选 d 个的方案数。

那这是一个经典背包,O(n2m),可以获得 70 分。

接下来是这题 dp 状态比较神仙的部分。

fi,j,k 表示前 i 个,TS(1)|T|k(|T|1k1)[iTai==j] 的值。注意此处 k 的定义与题面不同。

对于 i 这个数,要么选,要么不选。如果不选,直接继承状态。

如果选:

fi,j,k+=TS,iT(1)|T|k(|T|1k1)[xTax=j]=TS(1)|T|k+1(|T|k1)[xTax=jai]=TS(1)|T|k+1[(|T|1k1)+(|T|1k2)][xTax=jai]=(TS(1)|T|k+1(|T|1k1)+TS(1)|T|k+1(|T|1k2))[xTax=jai]=fi1,jai,k1fi1,jai,k

边界条件是 f0,0,0=1

非常的牛逼。

#include<bits/stdc++.h>
#define rep(i,a,b) for (register int i=(a);i<=(b);i++)
#define drep(i,a,b) for (register int i=(a);i>=(b);i--)
typedef long long ll;
using namespace std;
inline ll read()
{
	ll sum=0,f=0;char c=getchar();
	while (!isdigit(c)) f|=(c=='-'),c=getchar();
	while (isdigit(c)) sum=(sum<<1)+(sum<<3)+(c^48),c=getchar();
	return f?-sum:sum;
}

const int mod=998244353;
inline int qmo(int x){return x+((x>>31)&mod);}
inline int add(int x,int y){return qmo(x+y-mod);}
inline int sub(int x,int y){return qmo(x-y);}
inline void inc(int &x,int y){x=add(x,y);}
inline void dec(int &x,int y){x=sub(x,y);}
inline int quick_pow(int x,int k){int res=1;for (;k;k>>=1,x=1ll*x*x%mod) if (k&1) res=1ll*res*x%mod;return res;} 

const int N=1010;
const int M=10010;
const int K=15;

int fac[M],_fac[M],pw[M];
inline void init(int size)
{
	*fac=*_fac=*pw=1;
	rep(i,1,size) pw[i]=mod-pw[i-1];
	rep(i,1,size) fac[i]=1ll*fac[i-1]*i%mod;
	_fac[size]=quick_pow(fac[size],mod-2);
	drep(i,size-1,1) _fac[i]=1ll*_fac[i+1]*(i+1)%mod;
}
inline int C(int n,int m){return n>=m&&m>=0?1ll*fac[n]*_fac[m]%mod*_fac[n-m]%mod:0;}
inline int inv(int x){return 1ll*fac[x-1]*_fac[x]%mod;}

int n,k,m,g[2][M][K],f[N],a[N],ans;

int main()
{
	n=read(),k=n-read()+1,m=read(); rep(i,1,n) a[i]=read();
	g[0][0][0]=1; init(M-10);
	rep(i,1,n)
	{
		int t=i&1; memset(g[t],0,sizeof(g[t]));
		rep(j,0,m) rep(d,0,k) inc(g[t][j][d],g[t^1][j][d]);
		rep(j,a[i],m) rep(d,1,k)
		{
			inc(g[t][j][d],sub(g[t^1][j-a[i]][d-1],g[t^1][j-a[i]][d]));
		}
	}
	rep(j,0,m) inc(ans,1ll*m*inv(j)%mod*g[n&1][j][k]%mod);
	cout<<ans<<endl;
}
posted @   ZSH_ZSH  阅读(37)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示