公式

D - 砂漠横断 / Crossing the Desert 解説 by admin

Claude 4.5 Opus

Overview

This problem asks for the minimum number of gas stations to stop at in order to cross a desert by car and reach the goal. We solve it efficiently by combining a greedy approach with a priority queue (heap).

Analysis

Key Insight

The key point of this problem is to think that “we can decide later which gas stations to stop at.”

In reality, we decide whether to stop at a gas station when we pass it, but as a thought experiment, consider that “fuel from passed gas stations can be used at any time later.” Then, only when we run out of fuel do we decide “which gas station we should have stopped at.”

Problems with the Naive Approach

Trying all combinations of gas stations would require checking \(2^N\) combinations, which is far too slow when \(N \leq 2 \times 10^5\).

Why Greedy Works

When fuel runs out, it’s optimal to consider that we stopped at the gas station with the most fuel among those we’ve passed.

Here’s why: - We want to minimize the number of stops - The more fuel we get from a single refueling, the farther we can go before running out again - Therefore, a greedy approach that always selects the maximum fuel gives us the optimal solution

Algorithm

  1. Sort gas stations by position
  2. Prepare a max heap to manage the fuel amounts of passed gas stations
  3. Move sequentially from position \(0\) to goal \(G\):
    • Calculate the distance to the next point (gas station or goal)
    • If fuel is insufficient, extract the maximum fuel from the heap and refuel (increment stop count by 1)
    • If still insufficient, output \(-1\)
    • After moving, add the fuel of the passed gas station to the heap

Concrete Example

For \(G = 10\), \(F = 3\), gas stations: \((2, 5), (6, 3)\)

State Current Position Fuel Heap Next Target
Initial 0 3 [] Position 2
Reached position 2 2 1 [5] Position 6
Moving to position 6 (fuel shortage) - - - Get 5 from heap
Reached position 6 6 2 [3] Position 10
Moving to position 10 (fuel shortage) - - Get 3 from heap
Goal 10 1 [] -

Number of stops: 2

Complexity

  • Time Complexity: \(O(N \log N)\)

    • Sorting takes \(O(N \log N)\)
    • Each gas station has at most one push and one pop operation on the heap, each taking \(O(\log N)\)
  • Space Complexity: \(O(N)\)

    • Required for storing gas station information and the heap

Implementation Notes

  1. Implementing a Max Heap: Python’s heapq is a min heap, so we use it as a max heap by inserting negative values

  2. Handling the Goal: By adding the goal as a gas station with fuel \(0\), we can write the loop uniformly

    stations.append((G, 0))
    
  3. Handling Fuel Shortage: Use a while loop to extract from the heap as much as needed. Since a single refueling may not be enough, repeated refueling may be necessary

Source Code

import heapq

def solve():
    N, G, F = map(int, input().split())
    stations = []
    for _ in range(N):
        p, r = map(int, input().split())
        stations.append((p, r))
    
    # Sort by position
    stations.sort()
    
    # Current fuel
    fuel = F
    # Current position
    pos = 0
    # Number of gas stations stopped at
    count = 0
    # Max heap managing fuel of passed gas stations (stored as negative values)
    available = []
    
    # Gas station index
    idx = 0
    
    # Process including the goal
    # Treat the goal as one of the points
    stations.append((G, 0))
    
    for next_pos, next_fuel in stations:
        # Distance to the next point
        dist = next_pos - pos
        
        # If fuel is insufficient, refuel from passed gas stations
        while fuel < dist and available:
            # Extract the maximum fuel
            fuel += -heapq.heappop(available)
            count += 1
        
        # If still insufficient, destination is unreachable
        if fuel < dist:
            print(-1)
            return
        
        # Move to the next point
        fuel -= dist
        pos = next_pos
        
        # Add this gas station to the list of available gas stations (except for the goal)
        if next_fuel > 0:
            heapq.heappush(available, -next_fuel)
    
    print(count)

solve()

This editorial was generated by claude4.5opus.

投稿日時:
最終更新: