Solution -「AGC 020F」Arcs on a Circle
Link.
在一个周长为 的圆周上放置长度分别为 的弧,每条弧的位置独立均匀随机。求圆周被弧的并完全覆盖的概率。
,,输入均为整数。
记一个几乎没见过的 trick。顺便,真就 越小题越难呗。
不妨设 ,首先取 的左端点为坐标 点,将圆弧展开成数轴,如此可以避免“某条弧跨过 点向后覆盖”的情况。由于 为整数,所以所有 的端点坐标一定可以表示为 ,其中 ,且 。忽略次要矛盾,。直接枚举 的左端点 大小关系,就把问题转化到离散情况。状压 DP 一下即可。复杂度 。
/*+Rainybunny+*/
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)
const int MAXN = 6, MAXC = 50;
int n, c, prm[MAXN + 5], l[MAXN];
double f[MAXN * MAXC + 5][1 << MAXN >> 1];
int main() {
scanf("%d %d", &n, &c);
rep (i, 0, n - 1) scanf("%d", &l[i]);
std::sort(l, l + n);
double ans = 0.; int all = 0;
rep (i, 0, n - 2) prm[i] = i;
do {
memset(f, 0, sizeof f);
f[l[n - 1] * n][0] = 1;
rep (i, 1, n * c) if (i % n) {
int r = i % n - 1;
rep (j, i, n * c) {
rep (S, 0, (1 << n >> 1) - 1) if (~S >> r & 1) {
f[std::min(c * n, std::max(j, i + l[prm[r]] * n))]
[S | 1 << r] += f[j][S];
}
}
}
ans += f[c * n][(1 << n >> 1) - 1], ++all;
} while (std::next_permutation(prm, prm + n - 1));
printf("%.12f\n", ans / all / pow(c, n - 1));
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现