B - りんご収穫 / Apple Harvest 解説 by admin
Claude 4.6 Opus (Thinking)Overview
Given \(N\) trees, we need to select a contiguous interval of at most \(M\) trees and maximize the total number of apples from trees within that interval satisfying \(H_i \geq K\). This can be solved efficiently using prefix sums and the sliding window technique.
Analysis
Problem Reformulation
When we select an interval \([L, R]\), the total number of apples that can be shipped is:
\[\sum_{i=L}^{R} A_i \quad \text{where} \quad A_i = \begin{cases} H_i & (H_i \geq K) \\ 0 & (H_i < K) \end{cases}\]
In other words, if we first construct a new array \(A\) where each element is “\(H_i\) if the tree meets the shipping criteria, \(0\) otherwise,” the problem reduces to finding the maximum sum of a contiguous subarray of length at most \(M\).
Key Observation: \(A_i \geq 0\)
For a general array, finding the “maximum sum of a subarray of length at most \(M\)” requires maintaining the minimum of the prefix sum using a sliding window minimum (e.g., with a deque).
However, since \(A_i \geq 0\) in this problem, the prefix sum \(\text{prefix}[i]\) is monotonically non-decreasing. This means:
- The sum of interval \([L, R]\) (1-indexed) is \(\text{prefix}[R] - \text{prefix}[L-1]\)
- To maximize this with a fixed \(R\), we need to minimize \(\text{prefix}[L-1]\)
- The range of \(L-1\) is \([\max(0, R-M),\, R-1]\), and since prefix is monotonically non-decreasing, the minimum is always achieved at the left endpoint \(\max(0, R-M)\)
This means it is always optimal to use the maximum allowed length \(M\) for the interval (making it shorter never helps).
Concrete Example
For \(N=5, M=3, K=3, H=[1, 5, 2, 4, 1]\):
- \(A = [0, 5, 0, 4, 0]\) (trees with height less than \(K=3\) become \(0\))
- \(\text{prefix} = [0, 0, 5, 5, 9, 9]\)
- Compute the window sum of width \(M=3\) for each right endpoint \(R\):
- \(R=1\): \(\text{prefix}[1] - \text{prefix}[0] = 0\)
- \(R=2\): \(\text{prefix}[2] - \text{prefix}[0] = 5\)
- \(R=3\): \(\text{prefix}[3] - \text{prefix}[0] = 5\)
- \(R=4\): \(\text{prefix}[4] - \text{prefix}[1] = 9\)
- \(R=5\): \(\text{prefix}[5] - \text{prefix}[2] = 4\)
- The maximum is \(9\) (interval \([2, 4]\))
Algorithm
- Construct array \(A\): \(A_i = H_i\) (when \(H_i \geq K\)), \(A_i = 0\) (otherwise)
- Compute prefix sums \(\text{prefix}\): \(\text{prefix}[0] = 0,\; \text{prefix}[i] = \text{prefix}[i-1] + A_{i-1}\)
- For each \(R = 1, 2, \ldots, N\), compute \(\text{prefix}[R] - \text{prefix}[\max(0, R-M)]\) and take the maximum
Complexity
- Time complexity: \(O(N)\) — array construction, prefix sum computation, and maximum search are each \(O(N)\)
- Space complexity: \(O(N)\) — for storing array \(A\) and the prefix sums
Implementation Notes
Since \(A_i \geq 0\), the prefix sum is monotonically non-decreasing, so there is no need for sliding window minimum management using a deque; a simple loop suffices
Since \(N\) can be as large as \(10^6\), fast input using
sys.stdin.buffer.read()is important in PythonWhen computing the left endpoint of the window as
max(0, R - M), be careful about the correspondence between 1-indexed and 0-indexed representationsSource Code
import sys
def main():
input_data = sys.stdin.buffer.read().split()
N = int(input_data[0])
M = int(input_data[1])
K = int(input_data[2])
H = [int(input_data[3 + i]) for i in range(N)]
# For each tree, if H[i] >= K, its contribution is H[i], else 0
# We need to find a window of size <= M that maximizes the sum of H[i] where H[i] >= K
# Create array of filtered values
A = [h if h >= K else 0 for h in H]
# Compute prefix sums
prefix = [0] * (N + 1)
for i in range(N):
prefix[i + 1] = prefix[i] + A[i]
# For each R (1-indexed end), the window starts at L where L >= R - M + 1 and L >= 1
# Sum = prefix[R] - prefix[L-1]
# To maximize, we want prefix[L-1] to be minimized over L in [max(1, R-M+1), R]
# i.e., prefix[j] minimized over j in [max(0, R-M), R-1]
# Since A[i] >= 0, prefix is non-decreasing, so the minimum prefix[j] is at j = max(0, R-M)
# Therefore the best window ending at position R (1-indexed) has sum = prefix[R] - prefix[max(0, R-M)]
ans = 0
for r in range(1, N + 1):
l_start = max(0, r - M)
s = prefix[r] - prefix[l_start]
if s > ans:
ans = s
print(ans)
main()
This editorial was generated by claude4.6opus-thinking.
投稿日時:
最終更新: