D - 果物狩りフェスティバル / Fruit Picking Festival 解説 by admin
Claude 4.6 Opus (Thinking)Overview
This is a problem where you can harvest at most one fruit at or below the stepladder’s height during each of \(M\) harvest chances, and you want to maximize the total deliciousness. It can be solved efficiently using a greedy approach with a heap.
Analysis
Key Insight: The order of harvest chances is not essential
At first glance, it seems like the order matters since chances occur in order \(j = 1, 2, \ldots, M\), but in fact only the “assignment” of which fruit is harvested with which stepladder matters.
For example, consider the case \(L = [3, 5, 2]\). An assignment where a fruit at height 2 is picked during the 3rd chance (stepladder height 2), and a fruit at height 4 is picked during the 2nd chance (stepladder height 5), is valid. In other words, we only need to satisfy the condition that “at most one fruit with height less than or equal to the stepladder is assigned to each stepladder.”
Problems with the naive approach
Trying all possible assignments leads to combinatorial explosion. Since \(N, M\) can be up to \(2 \times 10^5\), even \(O(NM)\) may not be fast enough.
Solution: Sort + Greedy
Sort the stepladder heights in ascending order and process them from smallest to largest. For each stepladder, select the most delicious fruit among those within reach.
Why this is optimal (exchange argument): - Fruits reachable by a shorter stepladder are always reachable by a taller stepladder - Therefore, there is no need to “save” fruits for later — picking the most delicious reachable fruit is always the best choice - Even if the optimal solution had a different assignment, it can be shown through exchange that it yields a value equal to or less than this greedy solution
Algorithm
- Sort the fruits in ascending order of height \(D_i\)
- Sort the stepladder heights \(L_j\) in ascending order
- Prepare a max-heap (priority queue)
- Process the sorted stepladders from smallest to largest:
- Add all not-yet-added fruits with height less than or equal to the current stepladder’s height to the heap
- If the heap is not empty, extract the fruit with the highest deliciousness and add it to the total
- Output the total
Concrete Example
Fruits: (height 2, deliciousness 10), (height 3, deliciousness 5), (height 5, deliciousness 8) Stepladders (sorted): [2, 4, 5]
- Stepladder 2: Fruits with height ≤ 2 → Add {deliciousness 10} to heap → Obtain 10
- Stepladder 4: Fruits with height ≤ 4 → Add {deliciousness 5} → Obtain 5
- Stepladder 5: Fruits with height ≤ 5 → Add {deliciousness 8} → Obtain 8
Total: \(10 + 5 + 8 = 23\)
Complexity
- Time complexity: \(O(N \log N + M \log M + (N + M) \log N)\)
- Sorting fruits: \(O(N \log N)\)
- Sorting stepladders: \(O(M \log M)\)
- Heap operations: Each fruit is pushed/popped at most once, so \(O(N \log N)\)
- Space complexity: \(O(N + M)\)
Implementation Notes
Since Python does not have a max-heap, we negate the values and use
heapq(min-heap)By using a fruit pointer
fruit_idxand adding sorted fruits to the heap sequentially from the beginning, we efficiently manage which fruits are reachable for each stepladderInput is read all at once using
sys.stdin.buffer.read()for faster I/OSource Code
import heapq
import sys
def main():
input_data = sys.stdin.buffer.read().split()
idx = 0
N = int(input_data[idx]); idx += 1
M = int(input_data[idx]); idx += 1
fruits = []
for i in range(N):
D = int(input_data[idx]); idx += 1
V = int(input_data[idx]); idx += 1
fruits.append((D, V))
L = []
for j in range(M):
L.append(int(input_data[idx])); idx += 1
# Sort fruits by height
fruits.sort(key=lambda x: x[0])
# Sort chances by L value
sorted_L = sorted(L)
# Greedy: process chances from smallest L to largest
# For each chance, add all fruits with D <= L to max-heap, pick the best
max_heap = [] # store negative values for max-heap
fruit_idx = 0
total = 0
for l in sorted_L:
# Add all fruits reachable with this ladder height
while fruit_idx < N and fruits[fruit_idx][0] <= l:
heapq.heappush(max_heap, -fruits[fruit_idx][1])
fruit_idx += 1
# Pick the most valuable fruit if available
if max_heap:
total += -heapq.heappop(max_heap)
print(total)
main()
This editorial was generated by claude4.6opus-thinking.
投稿日時:
最終更新: