zoukankan      html  css  js  c++  java
  • 2018 ACM-ICPC World Finals Gym-102482D Gem Island

    题目传送门

    分析:
    期望=总价值/方案数
    于是就想办法算这两个。。。
    每个村民一个宝石,每天一个村民的一个宝石一分为二
    相当于最初都没有宝石,每天一个村民可以获得一个宝石
    效果是等价的
    问题变成了将(d)个宝石随机分给(n)个村民,求拥有最多宝石的(r)个人手上宝石的价值和
    设将(d)个宝石分给(n)个村民的方案数为(F_{n,d})
    列出式子:

    [F_{i,j}=sum_{k=0}^{min(i,j)}inom{i}{k}F_{k,j-k} ]

    意义为枚举到目前还有(i-k)个村民手上还没有宝石,剩下的的(k)个村民一人得到一个宝石
    设将(d)个宝石分给(n)个村民的所有方案中,前(r)个人手上宝石的和的总和为(G_{n,d})
    列出式子:

    [G_{i,j}=sum_{k=0}^{min(i,j)}inom{i}{k}(G_{k,j-k}+min(k,r)F_{k,j-k}) ]

    意义与上面类似
    复杂度(O(n^3))

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    
    #define maxn 1005
    #define MOD 998244353
    
    using namespace std;
    
    inline int getint()
    {
    	int num=0,flag=1;char c;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
    	return num*flag;
    }
    
    int n,d,r;
    long double C[maxn][maxn],F[maxn][maxn],G[maxn][maxn];
    
    int main()
    {
    	n=getint(),d=getint(),r=getint();
    	for(int i=0;i<=max(n,d);i++)
    	{
    		C[i][0]=1;
    		for(int j=1;j<=i;j++)C[i][j]=C[i-1][j-1]+C[i-1][j];
    	}
    	F[0][0]=1;
    	for(int i=1;i<=n;i++)for(int j=0;j<=d;j++)for(int k=0;k<=min(i,j);k++)
    	{
    		F[i][j]+=C[i][k]*F[k][j-k];
    		G[i][j]+=C[i][k]*(G[k][j-k]+min(k,r)*F[k][j-k]);
    	}
    	printf("%.8lf
    ",double(G[n][d]/F[n][d])+r);
    }
    

  • 相关阅读:
    静态检查lua语法工具luacheck
    centos7系列:
    git submodule 教程
    CENTOS 7 安装redis
    python基本语法:
    彻底理解lib和dll
    C++语言的设计与演化(空白):
    《Effective C++》 目录:
    C++进阶书籍(转)
    学习的心态(转)
  • 原文地址:https://www.cnblogs.com/Darknesses/p/13195356.html
Copyright © 2011-2022 走看看