P6944 [ICPC 2018 WF] Gem Island 题解

\(a_i\) 表示 \(d\) 天后第 \(i\) 个人拥有的宝石数,则确定每天被选择的人的方案数为 \(\frac{d!}{\prod_{i=1}^n (a_i-1)!}\),确定宝石分裂顺序的方案数为 \(\prod_{i=1}^n(a_i-1)!\),可以发现得到任意一种 \(a\) 序列的方案数都为 \(d!\)

接下来考虑 dp,记 \(g_{S,i}\) 表示当前所有数的和为 \(S\),最大值有 \(i\) 个的方案数,\(f_{S,i}\) 表示 \(r\) 个最大值的和,直接转移即可:

\[g_{S,i}=\sum_{j=i}^n {j\choose i}g_{S-j,j}\\ f_{S,i}=\sum_{j=i}^n {j\choose i}(f_{S-j,j}+g_{S-j,j}\min(r,i))\\ \]

时间复杂度 \(\mathcal O(dn^2)\)

参考代码:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rept(i,a,b) for(int i=(a);i<(b);++i)
#define drep(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
int n,d,r;
double s1,s2,f[503][503],g[503][503],c[503][503];
signed main(){
	cin>>n>>d>>r;
	c[0][0]=1;
	rep(i,1,n){
		c[i][0]=1;
		rep(j,1,i)c[i][j]=c[i-1][j-1]+c[i-1][j];
	}
	g[0][n]=1;
	rept(s,0,d){
		drep(i,n,1){
			rep(k,1,i){
				if(s+k>d)break;
				g[s+k][k]+=g[s][i]*c[i][k];
				f[s+k][k]+=(f[s][i]+g[s][i]*min(r,k))*c[i][k];
			}
		}
	}
	rep(i,1,n)s1+=g[d][i],s2+=f[d][i];
	printf("%.10lf",s2/s1+r);
	return 0;
}
posted @   zifanwang  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示