D - 配送センターの稼働計画 / Operation Plan for Distribution Center 解説 by admin
Claude 4.5 OpusOverview
This problem asks you to choose a consecutive \(K\)-day operation period and minimize the total dissatisfaction (sum of absolute differences from desired dates) when delivering all packages.
Analysis
Key Observations
Packages within the period have 0 dissatisfaction: If a package’s desired date \(D_i\) falls within the operation period \([s, s+K-1]\), it can be delivered on the desired date, resulting in 0 dissatisfaction.
Optimal delivery date for packages outside the period:
- For packages with desired date \(D_i < s\) (before the period) → Delivering on the first day \(s\) is optimal → Dissatisfaction is \(s - D_i\)
- For packages with desired date \(D_i > s+K-1\) (after the period) → Delivering on the last day \(s+K-1\) is optimal → Dissatisfaction is \(D_i - (s+K-1)\)
Narrowing down candidates for starting day \(s\): Since \(s\) can be any positive integer, exhaustive search is impossible (\(K \leq 10^9\)). However, the optimal \(s\) is limited to cases where some package’s desired date becomes an endpoint of the period.
Why Can We Narrow Down the Candidates?
When we consider the cost function as a function of \(s\), it becomes a piecewise linear function. The slope changes at the moment when a package switches from “outside the period” to “inside the period”. This happens when \(s = D_i\) (package \(i\) is at the left endpoint) or \(s = D_i - K + 1\) (package \(i\) is at the right endpoint).
Therefore, the candidates are narrowed down to at most \(2N\).
Algorithm
- Sort the desired dates \(D\)
- If all desired dates fit within \(K\) days (\(D_{max} - D_{min} + 1 \leq K\)), the answer is 0
- Compute prefix sums \(prefix[i] = D_0 + D_1 + \ldots + D_{i-1}\)
- Enumerate candidate values of \(s\) (for each \(D_i\): \(s = D_i\) and \(s = D_i - K + 1\))
- Calculate the cost for each candidate \(s\) and find the minimum
Cost Calculation Method (with fixed \(s\))
Let the operation period be \([s, e]\) (where \(e = s + K - 1\)):
Overflow on the left: Total dissatisfaction for packages where \(D_j < s\)
- Let \(L\) be the count and \(S_L\) be the sum, then the cost is \(L \cdot s - S_L\)
Overflow on the right: Total dissatisfaction for packages where \(D_j > e\)
- Let \(R\) be the count and \(S_R\) be the sum, then the cost is \(S_R - R \cdot e\)
Using binary search and prefix sums, we can calculate the cost for each candidate in \(O(\log N)\).
Complexity
- Time complexity: \(O(N \log N)\)
- Sorting: \(O(N \log N)\)
- Building prefix sums: \(O(N)\)
- Cost calculation for each candidate (at most \(2N\)): \(O(N \log N)\)
- Space complexity: \(O(N)\)
- Storing the sorted array and prefix sums
Implementation Notes
Proper use of binary search:
bisect_left(D, s): Number of elements where \(D_j < s\) (count of elements less than \(s\))bisect_right(D, e): Number of elements where \(D_j \leq e\) (starting position of elements greater than \(e\))
Utilizing prefix sums: Precompute prefix sums to obtain range sums in \(O(1)\)
Removing duplicate candidates: Use a
setto manage candidates and avoid calculating the same \(s\) multiple timesHandling special cases: If all packages fit within \(K\) days, output 0 early and terminate
Source Code
import sys
from bisect import bisect_left, bisect_right
def solve():
input_data = sys.stdin.read().split()
N = int(input_data[0])
K = int(input_data[1])
D = [int(input_data[i + 2]) for i in range(N)]
D.sort()
# Case where all packages fit within K days
if D[-1] - D[0] + 1 <= K:
print(0)
return
# Compute prefix sums
# prefix[i] = D[0] + D[1] + ... + D[i-1]
prefix = [0] * (N + 1)
for i in range(N):
prefix[i + 1] = prefix[i] + D[i]
# Let the operation period be [s, s+K-1]
# If package i's desired date D[i] is within the period, dissatisfaction is 0
# If D[i] < s, delivering on day s is optimal → dissatisfaction is s - D[i]
# If D[i] > s+K-1, delivering on day s+K-1 is optimal → dissatisfaction is D[i] - (s+K-1)
# Candidates for optimal s are cases where some package's desired date becomes the left or right endpoint
# That is, s = D[i] or s = D[i] - K + 1
# When s is fixed:
# - Packages where D[j] < s: total dissatisfaction = (count) * s - (sum of those D[j])
# - Packages where D[j] > s + K - 1: total dissatisfaction = (sum of those D[j]) - (count) * (s + K - 1)
def calc_cost(s):
# Operation period [s, s + K - 1]
e = s + K - 1
# Count and sum where D[j] < s
left_count = bisect_left(D, s)
left_sum = prefix[left_count]
# Count and sum where D[j] > e
right_idx = bisect_right(D, e)
right_count = N - right_idx
right_sum = prefix[N] - prefix[right_idx]
cost = left_count * s - left_sum + right_sum - right_count * e
return cost
min_cost = float('inf')
# Enumerate candidate values of s
candidates = set()
for d in D:
candidates.add(d) # s = d (d is the left endpoint of the period)
candidates.add(d - K + 1) # s = d - K + 1 (d is the right endpoint of the period)
for s in candidates:
cost = calc_cost(s)
min_cost = min(min_cost, cost)
print(min_cost)
solve()
This editorial was generated by claude4.5opus.
投稿日時:
最終更新: