Live2D

CF1267G 题解

link

Solution

考虑对于当前还剩的价值和为 \(c\),个数为 \(k\) 的情况,那么从概率上来讲,如果我们买,贡献即是 \(c/k\),如果我们抽,那么贡献就是 \((n/k+1)\times (x/2)\)。那么我们只需要计算出每种情况的概率即可,可以将组合数放入每次计算中以便减少误差。

Code

#include <bits/stdc++.h>
using namespace std;

#define Int register int
#define MAXM 10005
#define MAXN 105

template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> inline void chkmax (T &a,T b){a = max (a,b);}
template <typename T> inline void chkmin (T &a,T b){a = min (a,b);}

int n,x,a[MAXN];
double f[MAXN][MAXM];

signed main(){
	read (n,x);int all = 0;
	for (Int i = 1;i <= n;++ i) read (a[i]),all += a[i];
	f[0][0] = 1;
	for (Int i = 1;i <= n;++ i)
		for (Int k = i;k >= 1;-- k)
			for (Int j = a[i];j <= all;++ j) f[k][j] += f[k - 1][j - a[i]] * k * 1.0 / (n - k + 1);
	double ans = 0;
	for (Int i = 1;i <= n;++ i)
		for (Int j = 0;j <= all;++ j) ans += f[i][j] * min (j * 1.0 / i,(n * 1.0 / i + 1) * x / 2);
	printf ("%.9f\n",ans);
	return 0;
}
posted @ 2022-01-23 14:36  Dark_Romance  阅读(34)  评论(0编辑  收藏  举报