公式

D - Maximize the Gap 解説 by en_translator


First, let us determine whether the answer is \(-1\). This is so-called interval scheduling, which is known to be solvable by the following algorithm:

  1. Initialize a sequence of chosen cloths with \(()\).
  2. Sort the cloths in ascending order of \(R _ i\), and process them in order:
    1. For the cloth \(\lbrack L _ j, R _ j\rbrack\) chosen last time, if \(R _ j\lt L _ i\), then choose cloth \(\lbrack L _ i,R _ i\rbrack\).
  3. If the final sequence has a length less than \(K\), the answer is \(-1\).

If a choice of score \(x\) is possible, there is no cloth from the right end of a chosen cloth before advancing to the right by \(x\). Therefore, a choice of score \(x\) or greater is possible if and only if:

For all positive real numbers \(\varepsilon\), the answer when the cloths cover \(\lbrack L _ i,R _ i+x-\varepsilon\rbrack\) is not \(-1\).

This property allows us to solve the problem with binary search.

#include <iostream>
#include <vector>
#include <algorithm>
#include <ranges>

int main() {
    using namespace std;
    unsigned N, K;
    cin >> N >> K;

    vector<pair<unsigned, unsigned>> cloth(N);
    for (auto&& [L, R] : cloth)
        cin >> L >> R;
    
    // sort by right end
    ranges::sort(cloth, {}, [](const auto& p){return p.second;});

    // find the maximum amount a cloth can be extend to the right with binary search
    unsigned ans{*ranges::partition_point(views::iota(0U, 1000000000U), [K, &cloth](const unsigned x){
        unsigned chosen{}, last{};
        // choose as many cloths as possible with interval scheduling
        for (const auto& [L, R] : cloth) {
            if (last <= L) {
                ++chosen;
                last = R + x + 1; // extend to the right by x
            }
        }
        // OK if K or more cloths can be chosen
        return chosen >= K;
    })};
    
    // If it can be extended one or more
    if (ans) {
        cout << ans << endl; // that is the answer
    } else { // Otherwise
        cout << -1 << endl; // -1
    }
    return 0;
}

投稿日時:
最終更新: