D - 配達ルートの分割 / Splitting Delivery Packages Editorial by admin
GPT 5.2 HighOverview
Given a sequence of loads \(A_1,\dots,A_N\), we want to divide them into \(K\) contiguous segments while maintaining their original order, maximizing the minimum segment sum.
Analysis
Key Observations
- Since the loads assigned to each truck must be contiguous, this is essentially a problem of dividing an array into \(K\) contiguous segments.
- The goal is to maximize the “minimum segment sum,” but directly searching for the “optimal partition” involves \(K-1\) partition points, leading to a massive number of combinations (brute-force search is infeasible).
Converting to a Decision Problem
Instead of directly finding the “maximum of the minimum segment sum,” consider the following decision problem:
For a given value \(x\), can the array be divided into \(K\) contiguous segments such that every segment sum is at least \(x\)?
If this is possible, then “the minimum segment sum can be made at least \(x\)” = “the answer is at least \(x\).”
Why a Greedy Approach Works for the Decision Problem
Since \(A_i \ge 1\) (positive values), the optimal strategy is to accumulate sums from left to right and cut a segment as soon as the sum reaches \(x\) or more.
- Cutting as early as possible leaves more elements for the remaining segments, thereby maximizing the number of segments we can create.
- Therefore, using this greedy method, we count “how many segments with sum at least \(x\) can be created,” and if we can create \(K\) or more, it is feasible.
Concrete Example
For \(A=[2,1,3,2,2],\ K=3,\ x=4\):
Greedily accumulating from the left:
- \(2+1+3=6 \ge 4\) → 1st segment
- Next, \(2+2=4 \ge 4\) → 2nd segment
- No elements remain, so only 2 segments can be formed, not \(3\) → infeasible
Algorithm
1. Binary Search (Searching for the Answer)
Binary search for the answer (the minimum segment sum we want to maximize) over the range \(0\) to \(\sum A_i\).
- Try a value \(mid\); if
feasible(mid)described below returns True, “we might be able to go larger,” so setlo = mid - If False, “it’s too large,” so set
hi = mid - 1
2. Decision Function feasible(x) (Greedy)
Accumulate a running sum s from left to right. Whenever s >= x, cut a segment, increment the segment count cnt, and reset s = 0.
Return True as soon as cnt >= K (we successfully created \(K\) segments).
This method is correct because, for a sequence of positive numbers, the “cut as soon as the threshold is reached” strategy maximizes the number of segments, which is sufficient for the feasibility check.
Complexity
- Time complexity: \(O(N \log(\sum A_i))\)
(Binary search runs approximately \(\log(\sum A_i)\) iterations, each scanning the array once in \(O(N)\)) - Space complexity: \(O(1)\) (only constants beyond the input array)
Implementation Notes
To prevent infinite loops in binary search, use ceiling division for the midpoint:
mid = (lo + hi + 1) // 2(this is the standard technique when updatinglo).In
feasible, returning True immediately whencnt >= Kprovides a slight speedup.The upper bound
hiis at most \(\sum A_i\) (the sum when all loads are placed on a single truck), which is sufficient.Source Code
import sys
def main():
input = sys.stdin.readline
N, K = map(int, input().split())
A = list(map(int, input().split()))
total = sum(A)
def feasible(x: int) -> bool:
cnt = 0
s = 0
for a in A:
s += a
if s >= x:
cnt += 1
s = 0
if cnt >= K:
return True
return cnt >= K
lo, hi = 0, total
while lo < hi:
mid = (lo + hi + 1) // 2
if feasible(mid):
lo = mid
else:
hi = mid - 1
print(lo)
if __name__ == "__main__":
main()
This editorial was generated by gpt-5.2-high.
posted:
last update: