链接:
题意:
有一个长度为
C
的环,有
题解:
为了方便,取 L 最大的圆弧的放置位置的左端点作为原点。
记其他圆弧的放置位置为
Fi
的值并不重要,事实上只需要考虑他们的大小关系,所以可以
(N−1)!
地枚举所有大小关系(它们出现概率都相等),接下来就可以DP了:一共有
N×C
个不同的出现位置,
f(i,j,k)
表示考虑前
i
个出现位置,当前放的圆弧状态为
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;
template <typename T> inline void Read(T &x) {
char c = getchar();
bool f = false;
for (x = 0; !isdigit(c); c = getchar()) {
if (c == '-') {
f = true;
}
}
for (; isdigit(c); c = getchar()) {
x = x * 10 + c - '0';
}
if (f) {
x = -x;
}
}
template <typename T> inline bool CheckMax(T &a, const T &b) {
return a < b ? a = b, true : false;
}
template <typename T> inline bool CheckMin(T &a, const T &b) {
return a > b ? a = b, true : false;
}
const int N = 305;
int n, m, a[N], per[N];
LL sum, cnt, f[N][35];
inline LL Solve() {
for (int i = 0; i <= n * m; ++i) {
for (int j = 0; j < 1 << n - 1; ++j) {
f[i][j] = 0;
}
}
f[n * a[n - 1]][0] = 1;
for (int i = 0; i < n * m; ++i) {
for (int j = i; j <= n * m; ++j) {
for (int k = 0; k < 1 << n - 1; ++k) {
if (i % n && !(k >> per[i % n - 1] & 1)) {
f[min(n * m, max(j, i + n * a[per[i % n - 1]]))][k | 1 << per[i % n - 1]] += f[j][k];
}
}
}
}
return f[n * m][(1 << n - 1) - 1];
}
int main() {
#ifdef wxh010910
freopen("d.in", "r", stdin);
#endif
Read(n), Read(m);
for (int i = 0; i < n; ++i) {
Read(a[i]);
}
sort(a, a + n);
for (int i = 0; i < n - 1; ++i) {
per[i] = i;
}
do {
sum += Solve();
++cnt;
} while (next_permutation(per, per + n - 1));
for (int i = 0; i < n - 1; ++i) {
cnt = cnt * m;
}
printf("%.12lf\n", (double)sum / cnt);
#ifdef wxh010910
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
return 0;
}