【UOJ449】【集训队作业2018】喂鸽子(概率DP)

传送门


题解:

暂时咕咕咕。


代码:

#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const

using std::cerr;
using std::cout;

cs int mod=998244353;
inline int add(int a,int b){a+=b-mod;return a+(a>>31&mod);}
inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
inline int mul(int a,int b){ll r=(ll)a*b;return r>=mod?r%mod:r;}
inline int power(int a,int b,int res=1){
	for(;b;b>>=1,a=mul(a,a))(b&1)&&(res=mul(res,a));
	return res;
}
inline void Inc(int &a,int b){a+=b-mod;a+=a>>31&mod;}
inline void Mul(int &a,int b){a=mul(a,b);}

cs int N=105,M=N*1001;
int n,k,S;
int f[N][M],g[N][M];
int fac[M],ifac[M],inv[M],s[N],c[M];
inline int C(int n,int m){return mul(fac[n],mul(ifac[m],ifac[n-m]));}

signed main(){
#ifdef zxyoi
	freopen("gugugu.in","r",stdin);
#endif
	scanf("%d%d",&n,&k);S=n*k;
	fac[0]=fac[1]=ifac[1]=ifac[0]=inv[0]=inv[1]=1;
	for(int re i=2;i<=S;++i){
		fac[i]=mul(fac[i-1],i);
		inv[i]=mul(mod-mod/i,inv[mod%i]);
		ifac[i]=mul(ifac[i-1],inv[i]);
	}
	for(int re i=0;i<=n;++i)s[i]=mul(n,inv[n-i]);
	for(int re i=k-1;i<S;++i)c[i]=C(i,k-1);
	f[0][0]=1;
	for(int re i=0;i<n;++i)
	for(int re j=0;j<S;++j)if(f[i][j]||g[i][j]){
		int nf=mul(f[i][j],inv[n-i]);
		int ng=mul(add(g[i][j],mul(f[i][j],s[i])),inv[n-i]);
		Inc(f[i][j+1],nf);Inc(g[i][j+1],ng);
		Inc(f[i+1][j+1],mul(nf,c[j-i*k]));
		Inc(g[i+1][j+1],mul(ng,c[j-i*k]));
	}
	cout<<mul(fac[n],g[n][S])<<"\n";
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值