Live2D

Solution -「AGC 020F」Arcs on a Circle

Description

  Link.

  在一个周长为 c 的圆周上放置长度分别为 l1,l2,,ln 的弧,每条弧的位置独立均匀随机。求圆周被弧的并完全覆盖的概率。

  n6c50,输入均为整数。

Solution

  记一个几乎没见过的 trick。顺便,真就 n 越小题越难呗。

  不妨设 l1ln,首先取 ln 的左端点为坐标 0 点,将圆弧展开成数轴,如此可以避免“某条弧跨过 0 点向后覆盖”的情况。由于 li 为整数,所以所有 l 的端点坐标一定可以表示为 k+ϵ,其中 ϵS[0,1),且 |S|n。忽略次要矛盾,|S|=n。直接枚举 l1..n1 的左端点 ϵ 大小关系,就把问题转化到离散情况。状压 DP 一下即可。复杂度 O(n!2nn2c2)

Code

/*+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;
}

posted @   Rainybunny  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示