2 条题解

  • 1
    @ 2026-9-30 16:13:26

    对于每对 (xi,yi)(x_i,y_i),可以看成一个区间 [xi,yi][x_i,y_i],问让所有的 cic_i 至少属于一个 [xj,yj][x_j,y_j],求∑yi−xi\sum{y_i-x_i}。

    对于每个相邻的 cic_i 到 ci+1c_{i+1},如果它们被分到了不同的区间里,那么这两个区间之间就不需要覆盖这段空隙,相当于从总长度里省掉了 ci+1−cic_{i+1}-c_i

    所以问题就变成了:排序后,把 nn 个点分成至多 kk 段,每段用一个区间覆盖,代价是这一段的最大值减最小值。要最小化总代价。

    先把 cc 从小到大排序。现在有 kk 个区间,相当于把序列切成 kk 段。每切一刀,就会少覆盖一个相邻空隙。

    总代价可以写成:

    (cn−c1)−∑被切掉的相邻空隙(c_n-c_1)-\sum \text{被切掉的相邻空隙}

    我们要让总代价最小,也就是要让被切掉的相邻空隙之和最大。因为最多切成 kk 段,所以最多只能切 k−1k-1 刀。于是贪心地选最大的 k−1k-1 个相邻空隙切掉即可。

    所以最终答案:

    $$ans=(c_n-c_1)-\sum_{i=1}^{k-1} \text{第 } i \text{ 大的相邻差}$$

    如果 k≥nk\ge n,每个点都可以单独用一个长度为 00 的区间覆盖,答案就是 00。

        if(k>=n){puts("0");return 0;} 
        sort(c+1,c+1+n);
        for(int i=1;i<n;i++)
            l[i]=c[i+1]-c[i];
        sort(l+1,l+1+n,cmp);
        long long ans=c[n]-c[1];
        for(int i=1;i<=k-1;i++) ans-=l[i];
        cout<<ans;
    

    这里 l[i]l[i] 就是相邻两个点之间的距离,排序后,前 k−1k-1 个就是最大的 k−1k-1 个空隙。 注意答案要用 long long,因为 cic_i 可以到 10910^9,总长度可能到 101410^{14} 级别。

    信息

    ID
    2766
    时间
    1000ms
    内存
    128MiB
    难度
    4
    标签
    (无)
    递交数
    16
    已通过
    11
    上传者