Open In App

Find minimum time to finish all jobs with given constraints

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array of jobs with different time requirements. There are K identical assignees available and we are also given how much time an assignee takes to do one unit of the job. Find the minimum time to finish all jobs with following constraints.
 

  • An assignee can be assigned only contiguous jobs. For example, an assignee cannot be assigned jobs 1 and 3, but not 2.
  • Two assignees cannot share (or co-assigned) a job, i.e., a job cannot be partially assigned to one assignee and partially to other.

Input :

K:     Number of assignees available.
T:     Time taken by an assignee to finish one unit 
       of job
job[]: An array that represents time requirements of 
       different jobs.

Examples : 
 

Input:  k = 2, T = 5, job[] = {4, 5, 10}
Output: 50
The minimum time required to finish all the jobs is 50.
There are 2 assignees available. We get this time by 
assigning {4, 5} to first assignee and {10} to second 
assignee.

Input:  k = 4, T = 5, job[] = {10, 7, 8, 12, 6, 8}
Output: 75
We get this time by assigning {10} {7, 8} {12} and {6, 8}

We strongly recommend you to minimize your browser and try this yourself first. 
The idea is to use Binary Search. Think if we have a function (say isPossible()) that tells us if it’s possible to finish all jobs within a given time and number of available assignees. We can solve this problem by doing a binary search for the answer. If the middle point of binary search is not possible, then search in second half, else search in first half. Lower bound for Binary Search for minimum time can be set as 0. The upper bound can be obtained by adding all given job times. 
Now how to implement isPossible()? This function can be implemented using Greedy Approach. Since we want to know if it is possible to finish all jobs within a given time, we traverse through all jobs and keep assigning jobs to current assignee one by one while a job can be assigned within the given time limit. When time taken by current assignee exceeds the given time, create a new assignee and start assigning jobs to it. If the number of assignees becomes more than k, then return false, else return true.
 

C++




// C++ program to find minimum time to finish all jobs with
// given number of assignees
#include<bits/stdc++.h>
using namespace std;
 
// Utility function to get maximum element in job[0..n-1]
int getMax(int arr[], int n)
{
   int result = arr[0];
   for (int i=1; i<n; i++)
      if (arr[i] > result)
         result = arr[i];
    return result;
}
 
// Returns true if it is possible to finish jobs[] within
// given time 'time'
bool isPossible(int time, int K, int job[], int n)
{
    // cnt is count of current assignees required for jobs
    int cnt = 1;
 
    int curr_time = 0; //  time assigned to current assignee
 
    for (int i = 0; i < n;)
    {
        // If time assigned to current assignee exceeds max,
        // increment count of assignees.
        if (curr_time + job[i] > time) {
            curr_time = 0;
            cnt++;
        }
        else { // Else add time of job to current time and move
               // to next job.
            curr_time += job[i];
            i++;
        }
    }
 
    // Returns true if count is smaller than k
    return (cnt <= K);
}
 
// Returns minimum time required to finish given array of jobs
// k --> number of assignees
// T --> Time required by every assignee to finish 1 unit
// m --> Number of jobs
int findMinTime(int K, int T, int job[], int n)
{
    // Set start and end for binary search
    // end provides an upper limit on time
    int end = 0, start = 0;
    for (int i = 0; i < n; ++i)
        end += job[i];
 
    int ans = end; // Initialize answer
 
    // Find the job that takes maximum time
    int job_max = getMax(job, n);
 
    // Do binary search for minimum feasible time
    while (start <= end)
    {
        int mid = (start + end) / 2;
 
        // If it is possible to finish jobs in mid time
        if (mid >= job_max && isPossible(mid, K, job, n))
        {
            ans = min(ans, mid);  // Update answer
            end = mid - 1;
        }
        else
            start = mid + 1;
    }
 
    return (ans * T);
}
 
// Driver program
int main()
{
    int job[] =  {10, 7, 8, 12, 6, 8};
    int n = sizeof(job)/sizeof(job[0]);
    int k = 4, T = 5;
    cout << findMinTime(k, T, job, n) << endl;
    return 0;
}


Java




// Java program to find minimum time
// to finish all jobs with given
// number of assignees
 
class GFG
{
    // Utility function to get
    // maximum element in job[0..n-1]
    static int getMax(int arr[], int n)
    {
    int result = arr[0];
    for (int i=1; i<n; i++)
        if (arr[i] > result)
            result = arr[i];
        return result;
    }
     
    // Returns true if it is possible to finish jobs[]
    // within given time 'time'
    static boolean isPossible(int time, int K,
                                    int job[], int n)
    {
        // cnt is count of current
        // assignees required for jobs
        int cnt = 1;
         
        // time assigned to current assignee
        int curr_time = 0;
     
        for (int i = 0; i < n;)
        {
            // If time assigned to current assignee
            // exceeds max, increment count of assignees.
            if (curr_time + job[i] > time) {
                curr_time = 0;
                cnt++;
            }
             
            // Else add time of job to current
            // time and move to next job.
            else
            {
                curr_time += job[i];
                i++;
            }
        }
     
        // Returns true if count
        // is smaller than k
        return (cnt <= K);
    }
     
    // Returns minimum time required to
    // finish given array of jobs
    // k --> number of assignees
    // T --> Time required by every assignee to finish 1 unit
    // m --> Number of jobs
    static int findMinTime(int K, int T, int job[], int n)
    {
        // Set start and end for binary search
        // end provides an upper limit on time
        int end = 0, start = 0;
        for (int i = 0; i < n; ++i)
            end += job[i];
             
        // Initialize answer
        int ans = end;
     
        // Find the job that takes maximum time
        int job_max = getMax(job, n);
     
        // Do binary search for
        // minimum feasible time
        while (start <= end)
        {
            int mid = (start + end) / 2;
     
            // If it is possible to finish jobs in mid time
            if (mid >= job_max && isPossible(mid, K, job, n))
            {
                // Update answer
                ans = Math.min(ans, mid);
                 
                end = mid - 1;
            }
 
            else
                start = mid + 1;
        }
     
        return (ans * T);
    }
     
    // Driver program
    public static void main(String arg[])
    {
        int job[] = {10, 7, 8, 12, 6, 8};
        int n = job.length;
        int k = 4, T = 5;
        System.out.println(findMinTime(k, T, job, n));
    }
}
 
// This code is contributed by Anant Agarwal.


Python3




# Python program to find minimum
# time to finish all jobs with
# given number of assignees
 
# Utility function to get maximum
# element in job[0..n-1]
def getMax(arr, n):
    result = arr[0]
    for i in range(1, n):
        if arr[i] > result:
            result = arr[i]
    return result
 
# Returns true if it is possible
# to finish jobs[] within given
# time 'time'
def isPossible(time, K, job, n):
     
    # cnt is count of current
    # assignees required for jobs
    cnt = 1
 
    # time assigned to current assignee
    curr_time = 0
 
    i = 0
    while i < n:
         
        # If time assigned to current
        # assignee exceeds max, increment
        # count of assignees.
        if curr_time + job[i] > time:
            curr_time = 0
            cnt += 1
        else:
             
            # Else add time of job to current
            # time and move to next job.
            curr_time += job[i]
            i += 1
 
    # Returns true if count is smaller than k
    return cnt <= K
 
# Returns minimum time required
# to finish given array of jobs
# k --> number of assignees
# T --> Time required by every assignee to finish 1 unit
# m --> Number of jobs
def findMinTime(K, T, job, n):
     
    # Set start and end for binary search
    # end provides an upper limit on time
    end = 0
    start = 0
    for i in range(n):
        end += job[i]
 
    ans = end # Initialize answer
 
    # Find the job that takes maximum time
    job_max = getMax(job, n)
 
    # Do binary search for minimum feasible time
    while start <= end:
        mid = int((start + end) / 2)
 
        # If it is possible to finish jobs in mid time
        if mid >= job_max and isPossible(mid, K, job, n):
            ans = min(ans, mid) # Update answer
            end = mid - 1
        else:
            start = mid + 1
 
    return ans * T
 
# Driver program
if __name__ == '__main__':
    job = [10, 7, 8, 12, 6, 8]
    n = len(job)
    k = 4
    T = 5
    print(findMinTime(k, T, job, n))
     
# this code is contributed by PranchalK


C#




// C# program to find minimum time
// to finish all jobs with given
// number of assignees
using System;
 
class GFG
{
    // Utility function to get
    // maximum element in job[0..n-1]
    static int getMax(int []arr, int n)
    {
      int result = arr[0];
      for (int i=1; i<n; i++)
        if (arr[i] > result)
            result = arr[i];
        return result;
    }
     
    // Returns true if it is possible to
    // finish jobs[] within given time 'time'
    static bool isPossible(int time, int K,
                          int []job, int n)
    {
        // cnt is count of current
        // assignees required for jobs
        int cnt = 1;
         
        // time assigned to current assignee
        int curr_time = 0;
     
        for (int i = 0; i < n;)
        {
            // If time assigned to current assignee
            // exceeds max, increment count of assignees.
            if (curr_time + job[i] > time) {
                curr_time = 0;
                cnt++;
            }
             
            // Else add time of job to current
            // time and move to next job.
            else
            {
                curr_time += job[i];
                i++;
            }
        }
     
        // Returns true if count
        // is smaller than k
        return (cnt <= K);
    }
     
    // Returns minimum time required to
    // finish given array of jobs
    // k --> number of assignees
    // T --> Time required by every assignee to finish 1 unit
    // m --> Number of jobs
    static int findMinTime(int K, int T, int []job, int n)
    {
        // Set start and end for binary search
        // end provides an upper limit on time
        int end = 0, start = 0;
        for (int i = 0; i < n; ++i)
            end += job[i];
             
        // Initialize answer
        int ans = end;
     
        // Find the job that takes maximum time
        int job_max = getMax(job, n);
     
        // Do binary search for
        // minimum feasible time
        while (start <= end)
        {
            int mid = (start + end) / 2;
     
            // If it is possible to finish jobs in mid time
            if (mid >= job_max && isPossible(mid, K, job, n))
            {
                // Update answer
                ans = Math.Min(ans, mid);
                 
                end = mid - 1;
            }
 
            else
                start = mid + 1;
        }
     
        return (ans * T);
    }
     
    // Driver program
    public static void Main()
    {
        int []job = {10, 7, 8, 12, 6, 8};
        int n = job.Length;
        int k = 4, T = 5;
        Console.WriteLine(findMinTime(k, T, job, n));
    }
}
 
// This code is contributed by Sam007.


Javascript




<script>
    // Javascript program to find minimum time
    // to finish all jobs with given
    // number of assignees
     
    // Utility function to get
    // maximum element in job[0..n-1]
    function getMax(arr, n)
    {
      let result = arr[0];
      for (let i=1; i<n; i++)
        if (arr[i] > result)
            result = arr[i];
        return result;
    }
       
    // Returns true if it is possible to
    // finish jobs[] within given time 'time'
    function isPossible(time, K, job, n)
    {
        // cnt is count of current
        // assignees required for jobs
        let cnt = 1;
           
        // time assigned to current assignee
        let curr_time = 0;
       
        for (let i = 0; i < n;)
        {
            // If time assigned to current assignee
            // exceeds max, increment count of assignees.
            if (curr_time + job[i] > time) {
                curr_time = 0;
                cnt++;
            }
               
            // Else add time of job to current
            // time and move to next job.
            else
            {
                curr_time += job[i];
                i++;
            }
        }
       
        // Returns true if count
        // is smaller than k
        return (cnt <= K);
    }
       
    // Returns minimum time required to
    // finish given array of jobs
    // k --> number of assignees
    // T --> Time required by every assignee to finish 1 unit
    // m --> Number of jobs
    function findMinTime(K, T, job, n)
    {
        // Set start and end for binary search
        // end provides an upper limit on time
        let end = 0, start = 0;
        for (let i = 0; i < n; ++i)
            end += job[i];
               
        // Initialize answer
        let ans = end;
       
        // Find the job that takes maximum time
        let job_max = getMax(job, n);
       
        // Do binary search for
        // minimum feasible time
        while (start <= end)
        {
            let mid = parseInt((start + end) / 2, 10);
       
            // If it is possible to finish jobs in mid time
            if (mid >= job_max && isPossible(mid, K, job, n))
            {
                // Update answer
                ans = Math.min(ans, mid);
                   
                end = mid - 1;
            }
   
            else
                start = mid + 1;
        }
       
        return (ans * T);
    }
     
    let job = [10, 7, 8, 12, 6, 8];
    let n = job.length;
    let k = 4, T = 5;
    document.write(findMinTime(k, T, job, n));
 
</script>


Output: 

75

Time complexity: O(nlogn)

The time complexity of the above algorithm is O(nlogn). The binary search requires O(logn) time and the for loop requires O(n) time. So, the overall time complexity is O(nlogn).

Space complexity: O(1)

The space required by the above algorithm is O(1), i.e., constant space is required for storing the variables used in the algorithm.

Thanks to Gaurav Ahirwar for suggesting above solution.

 



Last Updated : 02 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads