Given an integer target and an array arr[] consisting of N positive integers where arr[i] denotes the time required to score 1 point for the ith array element, the task is to find the minimum time required to obtain the score target from the given array.
Examples:
Input: arr[] = {1, 3, 3, 4}, target = 10
Output: 6
Explanation:
At time instant, t = 1: Score of the array: {1, 0, 0, 0}
At time instant, t = 2: Score of the array: {2, 0, 0, 0}
At time instant, t = 3: Score of the array: {3, 1, 1, 0}
At time instant, t = 4: Score of the array: {4, 1, 1, 1}
At time instant, t = 5: Score of the array: {5, 1, 1, 1}
At time instant, t = 6: Score of the array: {6, 2, 2, 1}
Total score of the array after t = 5 = 6 + 2 + 2 + 1 = 11 ( > 10). Therefore, theInput: arr[] = {2, 4, 3}, target = 20
Output: 20
Approach: The idea is to use Hashing to store the frequency of array elements and iterate over the Hashmap and keep updating the score until it reaches target. An important observation is that any element, arr[i] adds t / arr[i] to the score at any time instant t. Follow the steps below to solve the problem:
- Initialize a variable, say time, to store the minimum time required and sum with 0 to store the score at any time instant t.
- Store the frequency of array elements in a Hashmap M.
- Iterate until the sum is less than target and perform the following steps:
- Set sum to 0 and increment the value of time by 1.
- Now, traverse the hashmap M and increment the value of sum by frequency * (time / value) in each iteration.
- After completing the above steps, print the value of time as the result.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; Â
// Function to calculate minimum time // required to achieve given score target void findMinimumTime( int * p, int n,                      int target) {     // Store the frequency of elements     unordered_map< int , int > um; Â
    // Traverse the array p[]     for ( int i = 0; i < n; i++) { Â
        // Update the frequency         um[p[i]]++;     } Â
    // Stores the minimum time required     int time = 0; Â
    // Store the current score     // at any time instant t     int sum = 0; Â
    // Iterate until sum is at     // least equal to target     while (sum < target) { Â
        sum = 0; Â
        // Increment time with         // every iteration         time ++; Â
        // Traverse the map         for ( auto & it : um) { Â
            // Increment the points             sum += it.second                    * ( time / it.first);         }     } Â
    // Print the time required     cout << time ; } Â
// Driver Code int main() { Â Â Â Â int arr[] = { 1, 3, 3, 4 }; Â Â Â Â int N = sizeof (arr) / sizeof (arr[0]); Â Â Â Â int target = 10; Â
    // Function Call     findMinimumTime(arr, N, target); Â
    return 0; } |
Java
// Java program for the above approach import java.util.*; import java.io.*;   class GFG{       // Function to calculate minimum time // required to achieve given score target static void findMinimumTime( int [] p, int n,                             int target) {           // Store the frequency of elements     HashMap<Integer,             Integer> um = new HashMap<>();                                               // Traverse the array p[]     for ( int i = 0 ; i < n; i++)     {                   // Update the frequency         if (!um.containsKey(p[i]))             um.put(p[i], 1 );         else             um.put(p[i],             um.get(p[i]) + 1 );     }       // Stores the minimum time required     int time = 0 ;       // Store the current score     // at any time instant t     int sum = 0 ;           while (sum < target)     {         sum = 0 ;                   // Increment time with         // every iteration         time++;           // Traverse the map         for (Map.Entry<Integer,                  Integer> it : um.entrySet())         {                           // Increment the points             sum += it.getValue() * (time / it.getKey());         }     }       // Print the time required     System.out.println(time); } Â
// Driver Code public static void main(String args[]) {     int [] arr = { 1 , 3 , 3 , 4 };     int N = arr.length;     int target = 10 ;           // Function Call     findMinimumTime(arr, N, target); } } Â
// This code is contributed by susmitakundugoaldanga |
Python3
# Python3 program for the above approach Â
# Function to calculate minimum time # required to achieve given score target def findMinimumTime(p, n, target):          # Store the frequency of elements     um = {} Â
    # Traverse the array p[]     for i in range (n): Â
        # Update the frequency         um[p[i]] = um.get(p[i], 0 ) + 1 Â
    # Stores the minimum time required     time = 0 Â
    # Store the current score     # at any time instant t     sum = 0 Â
    # Iterate until sum is at     # least equal to target     while ( sum < target): Â
        sum = 0 Â
        # Increment time with         # every iteration         time + = 1 Â
        # Traverse the map         for it in um: Â
            # Increment the points             sum + = um[it] * (time / / it) Â
    # Print time required     print (time) Â
# Driver Code if __name__ = = '__main__' : Â Â Â Â arr = [ 1 , 3 , 3 , 4 ] Â Â Â Â N = len (arr) Â Â Â Â target = 10 Â
    # Function Call     findMinimumTime(arr, N, target) Â
# This code is contributed by mohit kumar 29 |
C#
// C# program for the above approach using System.Collections.Generic; using System; using System.Linq; Â
class GFG{ Â
// Function to calculate minimum time // required to achieve given score target static void findMinimumTime( int [] p, int n,                             int target) {          // Store the frequency of elements     Dictionary< int ,                int > um = new Dictionary< int ,                                         int >();                                              // Traverse the array p[]     for ( int i = 0; i < n; i++)     {                  // Update the frequency         if (um.ContainsKey(p[i]) == true )             um[p[i]] += 1;         else             um[p[i]] = 1;     } Â
    // Stores the minimum time required     int time = 0; Â
    // Store the current score     // at any time instant t     int sum = 0; Â
    // Iterate until sum is at     // least equal to target     var val = um.Keys.ToList();          while (sum < target)     {         sum = 0;                  // Increment time with         // every iteration         time++; Â
        // Traverse the map         foreach ( var key in val)         {                          // Increment the points             sum += um[key] * (time / key);         }     } Â
    // Print the time required     Console.WriteLine(time); } Â
// Driver Code public static void Main() {     int []arr = { 1, 3, 3, 4 };     int N = arr.Length;     int target = 10;          // Function Call     findMinimumTime(arr, N, target); } } Â
// This code is contributed by Stream_Cipher |
Javascript
<script> Â
// Js program for the above approach // Function to calculate minimum time // required to achieve given score target function findMinimumTime( p, n,                       target) {     // Store the frequency of elements     let um = new Map(); Â
    // Traverse the array p[]     for (let i = 0; i < n; i++) { Â
        // Update the frequency         if (um[p[i]])         um[p[i]]++;         else         um[p[i]] = 1     } Â
    // Stores the minimum time required     let time = 0; Â
    // Store the current score     // at any time instant t     let sum = 0; Â
    // Iterate until sum is at     // least equal to target     while (sum < target) { Â
        sum = 0; Â
        // Increment time with         // every iteration         time++; Â
        // Traverse the map         for (let it in um) { Â
            // Increment the points             sum += um[it]                    * Math.floor(time / it);         }     } Â
    // Print the time required     document.write(time); } Â
// Driver Code let arr =Â [1, 3, 3, 4]; Â Â Â Â let N = arr.length; Â Â Â Â let target = 10; Â
    // Function Call     findMinimumTime(arr, N, target); Â
// This code is contributed by rohitsingh07052. </script> |
6
Time Complexity- 0(target*N)
Auxiliary Space- 0(N)
Optimised Approach:
If we use binary search here for l=1 to h=target until we find the minimum time for which we reach the target score for time t the target score is a[0]/t+a[1]/t+….. if it is greater than equal to target then this time is possible.
C++
#include <iostream> using namespace std; bool possible( int arr[], int n, int target, int mid){   int sum=0;      for ( int i=0;i<n;i++)   {     sum+=mid/arr[i];     if (sum>=target) return true ;   }      return false ;    } int solve( int arr[], int target, int n) {   int l=1;   int h=target;   int ans=0;   while (l<=h)   {     int mid=l+(h-l)/2;     if (possible(arr,n,target,mid))     {       ans=mid;       h=mid-1;     }     else       l=mid+1;   }      return ans; } int main() { Â
    int arr[]={1,3,3,4};     int target=10;     int n= sizeof (arr)/ sizeof (arr[0]);     cout<<solve(arr,target,n)<<endl;     return 0; } |
Java
public class Main {     public static boolean possible( int [] arr, int n, int target, int mid) {         /*         Returns true if it's possible to get at least 'target'         elements from the 'arr' array         using a division of 'mid', false otherwise.         */         int sum = 0 ;         for ( int i = 0 ; i < n; i++) {             sum += mid / arr[i];             if (sum >= target) {                 return true ;             }         }         return false ;     } Â
    public static int solve( int [] arr, int target, int n) {         /*         Finds the largest integer 'ans' such that         it's possible to get at least 'target' elements         from the 'arr' array using a division of 'ans'.         */         int l = 1 ;         int h = target;         int ans = 0 ;         while (l <= h) {             int mid = l + (h - l) / 2 ;             if (possible(arr, n, target, mid)) {                 ans = mid;                 h = mid - 1 ;             } else {                 l = mid + 1 ;             }         }         return ans;     } Â
    public static void main(String[] args) {         int [] arr = { 1 , 3 , 3 , 4 };         int target = 10 ;         int n = arr.length;         System.out.println(solve(arr, target, n));     } } |
Python3
def possible(arr, n, target, mid):     """     Returns True if it's possible to get at least 'target' elements from the 'arr' array     using a division of 'mid', False otherwise.     """     sum = 0     for i in range (n):         sum + = mid / / arr[i]         if sum > = target:             return True     return False Â
def solve(arr, target, n):     """     Finds the largest integer 'ans' such that it's possible to get at least 'target' elements     from the 'arr' array using a division of 'ans'.     """     l = 1     h = target     ans = 0     while l < = h:         mid = l + (h - l) / / 2         if possible(arr, n, target, mid):             ans = mid             h = mid - 1         else :             l = mid + 1     return ans Â
if __name__ = = "__main__" : Â Â Â Â arr = [ 1 , 3 , 3 , 4 ] Â Â Â Â target = 10 Â Â Â Â n = len (arr) Â Â Â Â print (solve(arr, target, n)) |
C#
using System; Â
class GFG {     public static bool Possible( int [] arr, int n,                                 int target, int mid)     {               /*         Returns true if it's possible to get at least 'target'         elements from the 'arr' array         using a division of 'mid', false otherwise.         */         int sum = 0;         for ( int i = 0; i < n; i++) {             sum += mid / arr[i];             if (sum >= target)                 return true ;         } Â
        return false ;     } Â
    public static int Solve( int [] arr, int target, int n)     {       /*         Finds the largest integer 'ans' such that         it's possible to get at least 'target' elements         from the 'arr' array using a division of 'ans'.         */         int l = 1;         int h = target;         int ans = 0;         while (l <= h) {             int mid = l + (h - l) / 2;             if (Possible(arr, n, target, mid)) {                 ans = mid;                 h = mid - 1;             }             else                 l = mid + 1;         } Â
        return ans;     } Â
    static void Main( string [] args)     {         int [] arr = { 1, 3, 3, 4 };         int target = 10;         int n = arr.Length;         Console.WriteLine(Solve(arr, target, n));     } } // This code is contributed by sarojmcy2e |
Javascript
// js code Â
function possible(arr, n, target, mid) { Â
    // Returns True if it's possible to get at least     // 'target' elements from the 'arr' array     // using a division of 'mid', False otherwise.     let sum = 0;     for (let i = 0; i < n; i++) {         sum += Math.floor(mid / arr[i]);         if (sum >= target) {             return true ;         }     }     return false ; } Â
function solve(arr, target, n) { Â
    // Finds the largest integer 'ans' such that     // it's possible to get at least 'target' elements     // from the 'arr' array using a division of 'ans'.     let l = 1;     let h = target;     let ans = 0;     while (l <= h) {         let mid = l + Math.floor((h - l) / 2);         if (possible(arr, n, target, mid)) {             ans = mid;             h = mid - 1;         } else {             l = mid + 1;         }     }     return ans; } Â
let arr = [1, 3, 3, 4]; let target = 10; let n = arr.length; console.log(solve(arr, target, n)); // 8 |
6
Time Complexity: O(log(target)*N)
Auxiliary Space: O(1)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!