Official

D - ロープの分割 / Splitting a Rope Editorial by admin

Qwen3-Coder-480B

Overview

A problem where you cut a rope at interval boundaries to divide it into exactly \(K\) pieces, minimizing the length of the longest piece.

Analysis

The goal of this problem is to minimize the “length of the longest piece” when dividing the rope into \(K\) pieces. A naive approach would be to try all possible ways of cutting, but since the number of intervals \(N\) can be up to \(10^5\), this is impractical due to combinatorial explosion.

The key observation is that binary search can be applied to the “minimum value of the longest piece’s length.” In other words, if we can solve the decision problem “Can we make all pieces have length at most \(X\)?”, then we can find the minimum \(X\) using binary search.

In the decision function can_split, we use a greedy approach to group the intervals sequentially. If adding an interval to the current group does not cause its length to exceed \(X\), we add it; otherwise, we start a new group. If the number of groups exceeds \(K\), we determine that \(X\) is not feasible.

By reducing the optimization problem to a “Yes/No” decision problem in this way, we can solve it efficiently.

Algorithm

  1. Determine the binary search range:

    • Minimum: the length of the longest single interval (max(A))
    • Maximum: the total length of all intervals (sum(A))
  2. Perform binary search:

    • Take the midpoint mid and use the decision function can_split to check “Can we divide into \(K\) groups with each group having length at most mid?”
  3. Decision function can_split:

    • Iterate through each interval from the beginning, checking whether adding it to the current group would cause the length to exceed mid.
    • If it would exceed, start a new group and increment the group count.
    • Return False if the number of groups exceeds \(K\), or True if all intervals are successfully processed.
  4. Update the search range while finding the minimum mid.

Complexity

  • Time complexity: \(O(N \log(\text{sum}(A)))\)
  • Space complexity: \(O(1)\) (excluding input)

Implementation Notes

  • Pay attention to the binary search range: left = max(A), right = sum(A)

  • In can_split, immediately return False if any single interval exceeds max_len (edge case handling)

  • When greedily grouping intervals, correctly maintain the current sum and group count

    Source Code

def can_split(A, K, max_len):
    count = 1
    current_sum = 0
    for a in A:
        if a > max_len:
            return False
        if current_sum + a > max_len:
            count += 1
            current_sum = a
            if count > K:
                return False
        else:
            current_sum += a
    return True

def main():
    import sys
    input = sys.stdin.read
    data = input().split()
    N = int(data[0])
    K = int(data[1])
    A = list(map(int, data[2:]))

    left = max(A)
    right = sum(A)
    
    while left < right:
        mid = (left + right) // 2
        if can_split(A, K, mid):
            right = mid
        else:
            left = mid + 1
    
    print(left)

if __name__ == "__main__":
    main()

This editorial was generated by qwen3-coder-480b.

posted:
last update: