ABC382 C-F题解

C - Kaiten Sushi

把寿司都放到一个堆里,从前往后扫 A 数组,如果当前食客 Ai 小于等于堆顶,就取出堆顶,记录这份寿司被第 i 个人吃掉。复杂度 O(nlogm)

D - Keep Distance

搜索回溯,但每一步从 10 枚举到 m 会超时,剪一下枝 for (int i = 10; res.back() + i <= m - 10 * (n - siz - 1); i++)

E - Expansion Packs

fi 表示再拿 i 个稀有卡期望 fi 步,发现 fi=1+fig0+fi1g1+fi2g2+。把 fig0 移到等式左边,有 (1g0)fi=1+j=1ifijgj,其中 gj 表示从一个袋子里拿到 j 个稀有卡的概率。得到 dp 方程 fi=1+j=1ifijgj1g0

g 数组可以通过 O(n2) 的 dp 求出。设 dpi,j 表示一个袋子里前 i 张卡中有 j 个稀有卡的概率,于是有 dpi,j=dpi1,j1pi+dpi1,j(1pi),注意 j=0 时的边界情况。dpn,j 即为 gj

void solve() {
    using f128 = long double;
    int n, x;
    cin >> n >> x;
    vector<f128> p(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> p[i];
        p[i] /= 100;
    }
    vector dp(n + 1, vector<f128>(n + 1));
    dp[0][0] = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= i; j++) {
            dp[i][j] = dp[i - 1][j] * (1 - p[i]);
            if (j) dp[i][j] += dp[i - 1][j - 1] * p[i];
        }
    }
    vector<f128> f(x + 1, 1);
    vector<f128>& g = dp[n];
    f[0] = 0;
    for (int i = 1; i <= x; i++) {
        for (int j = 1; j <= min(n, i); j++)
            f[i] += f[i - j] * g[j];
        f[i] /= (1 - g[0]);
    }
    cout << fixed << setprecision(16) << f[x] << '\n';
}

F - Falling Stars

把横线从下到上排序,开一棵线段树记录每个位置摞了多少层。要加入一条横线的时候,先查询对应区间 [Ci,Ci+Li1] 的最小值(最高层数)r,则该横线的层数就是 r1,区间赋值 r1 即可。AC代码

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