Open In App

Minimize refills to reach end of path

Last Updated : 03 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an integer target which represents the total distance to be covered by a car on a straight road. Given another array, station[] of size N representing petrol pumps where ith petrol pump is station[i][0] position away from the start and has station[i][1] amount of fuel. The car has an infinite petrol capacity and starts with M amount of fuel. The task is to find the minimum number of times the car has to stop for refueling to reach the end when it uses one unit of fuel for moving one unit distance.

Note: If it reaches ith station with 0 fuel left, it can refuel from that petrol pump and all the fuel from a petrol pump can be transferred to the car.

Examples:

Input: target = 1, M = 1, stations = { }
Output: 0
Explanation:  As it is possible to reach the target without refueling.

Input: target = 100, M = 1, stations = { {10, 100} }
Output: -1
Explanation: It is not possible to reach the target (or even the first gas station).

Input: target = 100, M = 10, stations = { {10, 60}, {20, 30}, {30, 30}, {60, 40}}
Output: 2
Explanation: Starting with 10 units of fuel. 
Drive to position 10, expanding 10 units of fuel. 
Then refuel from 0 liters to 60 units of fuels. 
Then, drive from position 10 to position 60, and refuel 40 liters of gas. 
Then simply drive and reach the target. 
Hence there are 2 refueling stops along the way.

 

Naive Approach: The basic approach is to attempt every single combination of 1 refueling pump, then every single combination of 2 refueling stops, etc. and find the minimum form that.

Time Complexity: O(2N)  Because total number of possible combinations are NC1 + NC2 + NC3 + . . . + NCN = 2N.
Auxiliary Space: O(1)

Approach 1: Using Dynamic Programming

Steps:

  • Let t[i][j] be a maximum amount of fuel we can have, when we reached station number i and refueled j times before this station (not included). Let us also add two more points to our stops: starting one and ending one. 
  • Then, how we can update t[i][j]: we can either refuel on previous station, than we have t[i-1][j-1] minus distance we covered between i-1 and i stations and plus amount of fuel we get at last station or it can be t[i-1][j] plus distance we covered between i-1 and i stations.
  • If we have cand < 0 in our code, then it means we can not reach position i with j refuels, so we leave it equal to minus infinity. Finally, in the end we check last station and find the smallest index where value is not negative and return it. If You could never reach target, so return -1.

C++




// C++ code for the above approach:
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find minimum
// refuel stops
int minRefuelStops(int T, int F, vector<vector<int> >& S)
{
    int n = S.size();
    vector<vector<int>> t(n+1, vector<int>(n+1, 0));
    for(int i = 0; i<n+1; i++)
         t[i][0] = F;
 
     for(int i = 1; i < n+1; i++) {
         for(int j = 1; j <= i; j++) {
              t[i][j] = t[i-1][j];
              if(t[i-1][j-1] >= S[i-1][0]) {
                    t[i][j] = max(t[i][j], t[i-1][j-1] + S[i-1][1]);
                }
            }
        }
        for(int j = 0; j<n+1; j++) {
            if(t[n][j] >= T)
                return j;
        }
        return -1;
    }
 
// Driver code
int main()
{
    int target = 100;
    int M = 10;
    vector<vector<int> > stations = {
        { 10, 60 }, { 20, 30 }, { 30, 30 }, { 60, 40 }
    };
 
    // Function call
    cout << minRefuelStops(target, M, stations);
    return 0;
}


Java




// Java code for the above approach
 
import java.io.*;
 
class GFG {
 
    // Function to find minimum refuel stops
    static int minRefuelStops(int T, int F, int[][] S)
    {
        int n = S.length;
        int[][] t = new int[n + 1][n + 1];
        for (int i = 0; i < n + 1; i++)
            t[i][0] = F;
 
        for (int i = 1; i < n + 1; i++) {
            for (int j = 1; j <= i; j++) {
                t[i][j] = t[i - 1][j];
                if (t[i - 1][j - 1] >= S[i - 1][0]) {
                    t[i][j] = Math.max(t[i][j],
                                       t[i - 1][j - 1]
                                           + S[i - 1][1]);
                }
            }
        }
        for (int j = 0; j < n + 1; j++) {
            if (t[n][j] >= T)
                return j;
        }
        return -1;
    }
 
    public static void main(String[] args)
    {
        int target = 100;
        int M = 10;
        int[][] stations = {
            { 10, 60 }, { 20, 30 }, { 30, 30 }, { 60, 40 }
        };
 
        // Function call
        System.out.print(
            minRefuelStops(target, M, stations));
    }
}
 
// This code is contributed by lokeshmvs21.


Python3




# Python code for the above approach
 
# Function to find minimum refuel stops
def minRefuelStops(T, F, S):
    n = len(S)
    lst = []
    t = []
    for i in range(0, n+1):
        for j in range(0, n+1):
            lst.append(0)
        t.append(lst)
        lst = []
    for i in range(n+1):
        t[i][0] = F
    for i in range(1, n+1):
        for j in range(1, i+1):
            t[i][j] = t[i - 1][j]
            if (t[i - 1][j - 1] >= S[i - 1][0]):
                t[i][j] = max(t[i][j], t[i - 1][j - 1] + S[i - 1][1])
    for j in range(n+1):
        if (t[n][j] >= T):
            return j
    return -1
 
 
target = 100
M = 10
stations = [[10, 60], [20, 30], [30, 30], [60, 40]]
 
# Function call
print(minRefuelStops(target, M, stations))
 
# This code is contributed by vikkycirus


C#




// C# code for the above approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG {
 
  // Function to find minimum refuel stops
  static int minRefuelStops(int T, int F, int[, ] S)
  {
    int n = S.GetLength(0);
    int[, ] t = new int[n + 1, n + 1];
    for (int i = 0; i < n + 1; i++)
      t[i, 0] = F;
 
    for (int i = 1; i < n + 1; i++) {
      for (int j = 1; j <= i; j++) {
        t[i, j] = t[i - 1, j];
        if (t[i - 1, j - 1] >= S[i - 1, 0]) {
          t[i, j] = Math.Max(t[i, j],
                             t[i - 1, j - 1]
                             + S[i - 1, 1]);
        }
      }
    }
    for (int j = 0; j < n + 1; j++) {
      if (t[n, j] >= T)
        return j;
    }
    return -1;
  }
 
  public static void Main(string[] args)
  {
    int target = 100;
    int M = 10;
    int[, ] stations = {
      { 10, 60 }, { 20, 30 }, { 30, 30 }, { 60, 40 }
    };
 
    // Function call
    Console.Write(minRefuelStops(target, M, stations));
  }
}
 
// This code is contributed by karandeep1234.


Javascript




// Javascript code for the above approach
 
// Function to find minimum refuel stops
function minRefuelStops(T, F, S) {
    let n = S.length;
    let t = new Array(n + 1).fill(0).map(() => new Array(n + 1).fill(0))
    for (let i = 0; i < n + 1; i++)
        t[i][0] = F;
 
    for (let i = 1; i < n + 1; i++) {
        for (let j = 1; j <= i; j++) {
            t[i][j] = t[i - 1][j];
            if (t[i - 1][j - 1] >= S[i - 1][0]) {
                t[i][j] = Math.max(t[i][j],
                    t[i - 1][j - 1]
                    + S[i - 1][1]);
            }
        }
    }
    for (let j = 0; j < n + 1; j++) {
        if (t[n][j] >= T)
            return j;
    }
    return -1;
}
 
let target = 100;
let M = 10;
let stations = [
    [10, 60], [20, 30], [30, 30], [60, 40]
];
 
// Function call
console.log(minRefuelStops(target, M, stations));
 
// This code is contributed by Saurabh Jaiswal


Output

2

Time Complexity: O(N^2)
Auxiliary Space: O(N^2)

 Approach 2: This problem can be solved using a Greedy approach and max heap based on the following idea:

  • As there is need to refuel minimum number of times so do not refill the tank till it is possible to reach the next petrol pump.
  • When it is no more possible to reach the next petrol pump, select one pump from the ones crossed till now and not used for refueling.
  • To minimize the stops it is optimal to choose the petrol pump with maximum amount of fuel.

To find the pump with maximum one from the already visited ones in optimal time, use max heap. Store the petrol pumps in max heap while crossing them, and remove it from the heap when  it is used.

Follow the below steps to solve the problem:

  • Sort the stations in ascending order of their position from the start.
  • Create a max heap say pq(implemented by priority queue).
  • Traverse the stations from i = 0 to N-1:
    • Check if the car can reach ith station without refueling.
    • If it cannot reach, then find the station from the max heap which has maximum fuel and is not used for refueling among the stations crossed till now and increment the count of refueling stops.
    • Insert the ith station in the max heap
  • Return the count as the answer.

Below is the implementation of the above approach:

C++14




// C++ code for the above approach:
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find minimum
// refuel stops
int minRefuelStops(int T, int F,
                   vector<vector<int> >& S)
{
    int N = S.size(), ans = 0;
    sort(S.begin(), S.end());
 
    // Initializing max heap
    priority_queue<int> pq;
    for (int i = 0; i <= N; i++) {
        int dist = i == N ? T : S[i][0];
        while (F < dist) {
            if (!pq.size())
                return -1;
            F += pq.top(), ans++;
            pq.pop();
        }
        if (i < N)
            pq.push(S[i][1]);
    }
    return ans;
}
 
// Driver code
int main()
{
    int target = 100;
    int M = 10;
    vector<vector<int> > stations = {
        { 10, 60 }, { 20, 30 }, { 30, 30 }, { 60, 40 }
    };
 
    // Function call
    cout << minRefuelStops(target, M, stations);
    return 0;
}


Java




// Java code to implement the approach
 
import java.util.*;
 
public class GFG {
    // Function to find the minimum number
    // of refueling stops
    static int minRefuelStops(int T, int F,
                              int[][] S)
    {
        int N = S.length, ans = 0;
 
        // Sort on the basis of
        // distance from the start
        Arrays.sort(S, new Comparator<int[]>() {
            public int compare(int[] a, int[] b)
            {
                return Integer.compare(a[0], b[0]);
            }
        });
        PriorityQueue<Integer> pq
            = new PriorityQueue<>((a, b)
                                      -> b - a);
        for (int i = 0; i <= N; i++) {
            int dist = i == N ? T : S[i][0];
            while (F < dist) {
                if (pq.size() == 0)
                    return -1;
                F += pq.poll();
                ans++;
            }
            if (i < N)
                pq.add(S[i][1]);
        }
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int target = 100, M = 10;
        int stations[][] = {
            { 10, 60 }, { 20, 30 }, { 30, 30 }, { 60, 40 }
        };
        System.out.println(
            minRefuelStops(target, M, stations));
    }
}
// this code is contributed by prophet1999


Python3




# python code for the above approach
import heapq
 
# Function to find minimum refuel stops
def minRefuelStops(T, F, S):
    N = len(S)
    ans = 0
    S.sort()
 
    # Initializing max heap
    pq = []
    for i in range(N+1):
        dist = T if i == N else S[i][0]
        while F < dist:
            if len(pq)==0:
                return -1
            ans+=1
            F += -1*heapq.heappop(pq)
        if i < N:
            heapq.heappush(pq, -1*S[i][1])
    return ans
 
 
# Driver Code
target = 100
M = 10
stations = [[10, 60], [20, 30], [30, 30], [60, 40]]
print(minRefuelStops(target, M, stations))
 
# This code is contributed by ishankhandelwals.


C#




// C# code to implement the approach
using System;
using System.Collections.Generic;
 
public class GFG
{
 
  // Function to find the minimum number
  // of refueling stops
  static int minRefuelStops(int T, int F,
                            int[][] S)
  {
    int N = S.Length, ans = 0;
 
    // Sort on the basis of
    // distance from the start
    int compare(int[] a, int[] b)
    {
      for (int i = 0; i < Math.Min(a.Length, b.Length); i++)
      {
        if (a[i] < b[i])
          return -1;
        if (a[i] > b[i])
          return 1;
      }
      if (a.Length < b.Length)   
        return -1;
      if (a.Length == b.Length)
        return 0;
      return 1;
    }
 
    Array.Sort(S, compare);
 
    List<int> pq = new List<int>();
 
    for (int i = 0; i <= N; i++) {
      int dist = i == N ? T : S[i][0];
      while (F < dist) {
        if (pq.Count == 0)
          return -1;
        F += pq[0];
        ans++;
      }
      if (i < N)
      {
        pq.Add(S[i][1]);
        pq.Sort();
      }
    }
    return ans;
  }
 
  // Driver code
  public static void Main(string[] args)
  {
    int target = 100, M = 10;
    int[][] stations = { new int[]
    { 10, 60 }, new int[] { 20, 30 }, new int[] { 30, 30 }, new int[] { 60, 40 }
                       };
    Console.WriteLine(
      minRefuelStops(target, M, stations));
  }
}
 
// This code is contributed by phasing17


Javascript




// JS code for the above approach
 
// Function to find minimum refuel stops
function minRefuelStops(T, F, S)
{
    let N = S.length
    let ans = 0
    S.sort()
 
    // Initializing max heap
    let pq = []
    for (var i = 0; i <= N; i++)
    {
        let dist = (i == N) ? T : S[i][0]
        while (F < dist)
        {
            if (pq.length ==0)
                return -1
            ans+=1
            F += pq[0]
        }
        if (i < N)
        {
            pq.push(S[i][1])
            pq.sort()
        }
    }
    return ans
 
}
// Driver Code
let target = 100
let M = 10
let stations = [[10, 60], [20, 30], [30, 30], [60, 40]]
console.log(minRefuelStops(target, M, stations))
 
// This code is contributed by phasing17.


Output

2

Time Complexity: O(N * log N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads