1 条题解

  • 0
    @ 2026-5-4 17:33:54

    CF1988A Split the Multiset 题解

    题意简述

    初始多重集 S={n}S=\{n\},每次操作可以:

    1. 选择 SS 中的一个正整数 uu
    2. 移除它的一个副本;
    3. SS 中插入 不超过 kk 个正整数,它们的和等于 uu

    求使 SS 中恰包含 nn11 所需的最小操作次数。

    1n10001 \le n \le 10002k10002 \le k \le 1000


    核心思路

    每次操作相当于把一个大数“分裂”成若干小数,且分裂出的数的个数不超过 kk

    初始时集合中只有 11 个元素,最终我们需要 nn 个元素(全部是 11)。
    一次操作最多可以把 11 个元素变成 kk 个元素,因此每操作一次,元素总数最多增加 k1k-1

    要从 11 个元素变成 nn 个元素,至少需要操作

    n1k1\left\lceil \frac{n-1}{k-1} \right\rceil

    次。这就是所需答案的下界。


    构造方案(证明下界可达)

    我们可以采用如下贪心策略:

    • 每次选取当前集合中最大的数 xx(且 x>1x>1)。
    • xkx \ge k,将其分裂为 kk 个数:(1,1,,1k1 个,x(k1))(\underbrace{1,1,\dots,1}_{k-1\text{ 个}}, x-(k-1))
    • x<kx < k,则将其直接分裂为 xx11(此时不再有大于 11 的数,过程结束)。

    这样,每次操作(除最后一次外)都会恰好产生 k1k-1 个新的 11,同时保留一个剩余的大数供后续处理。最终,当剩余的那个数小于 kk 时,最后一次操作将其全部变成 11

    因此,总操作次数恰好为 (n1)/(k1)\lceil (n-1)/(k-1) \rceil,达到下界。


    答案公式

    • n=1n = 1 时,答案为 00
    • 否则答案为 (n1)/(k1)\lceil (n-1) / (k-1) \rceil

    在整数运算中可写成 (n - 1 + k - 2) / (k - 1) 或直接使用 ceil


    复杂度分析

    • 时间复杂度:O(1)O(1) 每组数据。
    • 空间复杂度:O(1)O(1)

    参考代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
    
        int t;
        cin >> t;
        while (t--) {
            int n, k;
            cin >> n >> k;
            if (n == 1) {
                cout << "0\n";
            } else {
                cout << (n - 1 + k - 2) / (k - 1) << '\n';
            }
        }
        return 0;
    }
    • 1

    信息

    ID
    6819
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者