Open In App

Find minimum time to finish all jobs with given constraints

Last Updated : 07 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array job[], where each element represents the time required to complete a specific job. There are k identical assignees available to complete these jobs, and each assignee takes t units of time to complete one unit of a job. The task is to determine the minimum time required to complete all jobs while following these constraints: 

  • Each assignee can only be assigned jobs that are contiguous in the given array. For example, an assignee can be assigned jobs (job[1], job[2], job[3]) but not (job[1], job[3]) (skipping job[2]).
  • A single job cannot be divided between two assignees. Each job must be assigned to exactly one assignee.

Examples:

Input: job[] = {10, 7, 8, 12, 6, 8}, k = 4, t = 5
Output: 75
Explanation: The minimum time required to finish all the jobs is 75.

  • Assign {10} to the first assignee.
  • Assign {7, 8} to the second assignee.
  • Assign {12} to the third assignee.
  • Assign {6, 8} to the fourth assignee.
  • Maximum time taken by any assignee is (12 * 5) = 75.


Input: job[] = {4, 5, 10}, k = 2, t = 5
Output: 50
Explanation: The minimum time required to finish all the jobs is 50.

  • Assign {4, 5} to the first assignee.
  • Assign {10} to the second assignee.
  • Maximum time taken by any assignee is (4 + 5) * 5 = 50.

This problem is mainly a variation of Allocate Minimum Pages

The idea is to use Binary Search, as we observe that the total job sum gives an upper bound, and the maximum job gives a lower bound. Using binary search between these bounds helps efficiently find the minimum feasible time. The key observation is that for a given time t, we can check if the jobs can be assigned within k assignees using a greedy approach. If it is possible, we try to minimize t further; otherwise, we increase it. This ensures an optimal partitioning of jobs while keeping time minimal.

Steps to implement the above idea:

  • Calculate the maximum job duration and total job sum to determine the search range.
  • Use binary search between the maximum job time and the total job time to find the minimum feasible time.
  • Implement a function to assign jobs to assignees while ensuring no one exceeds the given time limit.
  • If jobs can be completed within the current mid-value, update the answer and reduce the search space; otherwise, increase the lower bound.
  • Multiply the minimum feasible time by the given multiplier and print the result.

Below is the implementation of the above approach:

C++
// C++ program to find the minimum time required  
// to finish all jobs using Binary Search  
#include <bits/stdc++.h>
using namespace std;

// Function to find the maximum job duration  
int getMax(vector<int> &job) {
    int res = job[0];

    // Find the maximum time among all jobs  
    for (int i = 1; i < job.size(); i++) {  
        if (job[i] > res) {  
            res = job[i];  
        }
    }
    return res;
}

// Function to check if jobs can be completed within  
// 't' time  using at most 'k' assignees  
bool isPossible(vector<int> &job, int t, int k) {
    
    // Number of assignees required 
    int cnt = 1;   
    
    // Time assigned to the current assignee
    int curr = 0;    

    for (int i = 0; i < job.size();) {
        
        // If adding the current job exceeds 't',
        // assign a new assignee  
        if (curr + job[i] > t) {
            curr = 0;
            cnt++;
        } else {
            
            // Otherwise, add job time to the 
            // current assignee  
            curr += job[i];
            i++;
        }
    }
     
    return (cnt <= k);
}

// Function to find the minimum time required to
// finish all jobs  
int findMinTime(vector<int> &job, int k, int t) {
    int start = 0, end = 0, ans;

    // Compute the total time and the maximum
    // job duration  
    for (int j : job) {
        
        // Total sum of job times
        end += j; 
        
        // Maximum job duration
        start = max(start, j);    
    }
    
    // Initialize answer to the upper bound 
    ans = end;   

    // Perform binary search to find the minimum
    // feasible time  
    while (start <= end) {
        int mid = (start + end) / 2;

        // If jobs can be assigned within 'mid' time  
        if (isPossible(job, mid, k)) {
            ans = min(ans, mid);  
            end = mid - 1;  
        } else {
            start = mid + 1;  
        }
    }

    // Return the minimum time required  
    return ans * t;
}

int main() {
    vector<int> job = {10, 7, 8, 12, 6, 8};
    int k = 4, t = 5;
    
    cout << findMinTime(job, k, t) << endl;
    return 0;
}
Java
// Java program to find the minimum time required  
// to finish all jobs using Binary Search  
import java.util.*;

class GfG {

    // Function to find the maximum job duration  
    static int getMax(int job[]) {
        int res = job[0];

        // Find the maximum time among all jobs  
        for (int i = 1; i < job.length; i++) {  
            if (job[i] > res) {  
                res = job[i];  
            }
        }
        return res;
    }

    // Function to check if jobs can be completed within  
    // 't' time using at most 'k' assignees  
    static boolean isPossible(int job[], int t, int k) {
        
        // Number of assignees required 
        int cnt = 1;   
        
        // Time assigned to the current assignee
        int curr = 0;    

        for (int i = 0; i < job.length;) {
            
            // If adding the current job exceeds 't',
            // assign a new assignee  
            if (curr + job[i] > t) {
                curr = 0;
                cnt++;
            } else {
                
                // Otherwise, add job time to the 
                // current assignee  
                curr += job[i];
                i++;
            }
        }
        
        return (cnt <= k);
    }

    // Function to find the minimum time required to
    // finish all jobs  
    static int findMinTime(int job[], int k, int t) {
        int start = 0, end = 0, ans;

        // Compute the total time and the maximum
        // job duration  
        for (int j : job) {
            
            // Total sum of job times
            end += j; 
            
            // Maximum job duration
            start = Math.max(start, j);    
        }
        
        // Initialize answer to the upper bound 
        ans = end;   

        // Perform binary search to find the minimum
        // feasible time  
        while (start <= end) {
            int mid = (start + end) / 2;

            // If jobs can be assigned within 'mid' time  
            if (isPossible(job, mid, k)) {
                ans = Math.min(ans, mid);  
                end = mid - 1;  
            } else {
                start = mid + 1;  
            }
        }

        // Return the minimum time required  
        return ans * t;
    }

    public static void main(String[] args) {
        int job[] = {10, 7, 8, 12, 6, 8};
        int k = 4, t = 5;
        
        System.out.println(findMinTime(job, k, t));
    }
}
Python
# Python program to find the minimum time required  
# to finish all jobs using Binary Search  

# Function to find the maximum job duration  
def GetMax(job):  
    res = job[0]  

    # Find the maximum time among all jobs  
    for i in range(1, len(job)):  
        if job[i] > res:  
            res = job[i]  
    return res  

# Function to check if jobs can be completed within  
# 't' time using at most 'k' assignees  
def IsPossible(job, t, k):  

    # Number of assignees required  
    cnt = 1  

    # Time assigned to the current assignee  
    curr = 0  

    i = 0
    while i < len(job):  

        # If adding the current job exceeds 't',
        # assign a new assignee  
        if curr + job[i] > t:  
            curr = 0  
            cnt += 1  
        else:  

            # Otherwise, add job time to the  
            # current assignee  
            curr += job[i]  
            i += 1  

    return cnt <= k  

# Function to find the minimum time required to  
# finish all jobs  
def FindMinTime(job, k, t):  
    start, end = 0, 0  

    # Compute the total time and the maximum  
    # job duration  
    for j in job:  

        # Total sum of job times  
        end += j  

        # Maximum job duration  
        start = max(start, j)  

    # Initialize answer to the upper bound  
    ans = end  

    # Perform binary search to find the minimum  
    # feasible time  
    while start <= end:  
        mid = (start + end) // 2  

        # If jobs can be assigned within 'mid' time  
        if IsPossible(job, mid, k):  
            ans = min(ans, mid)  
            end = mid - 1  
        else:  
            start = mid + 1  

    # Return the minimum time required  
    return ans * t  

if __name__ == "__main__":   
    job = [10, 7, 8, 12, 6, 8]  
    k, t = 4, 5  

    print(FindMinTime(job, k, t))  
C#
// C# program to find the minimum time required  
// to finish all jobs using Binary Search  
using System;

class GfG {

    // Function to find the maximum job duration  
    static int GetMax(int[] job) {
        int res = job[0];

        // Find the maximum time among all jobs  
        for (int i = 1; i < job.Length; i++) {  
            if (job[i] > res) {  
                res = job[i];  
            }
        }
        return res;
    }

    // Function to check if jobs can be completed within  
    // 't' time using at most 'k' assignees  
    static bool IsPossible(int[] job, int t, int k) {
        
        // Number of assignees required 
        int cnt = 1;   
        
        // Time assigned to the current assignee
        int curr = 0;    

        for (int i = 0; i < job.Length;) {
            
            // If adding the current job exceeds 't',
            // assign a new assignee  
            if (curr + job[i] > t) {
                curr = 0;
                cnt++;
            } else {
                
                // Otherwise, add job time to the 
                // current assignee  
                curr += job[i];
                i++;
            }
        }
        
        return (cnt <= k);
    }

    // Function to find the minimum time required to
    // finish all jobs  
    static int FindMinTime(int[] job, int k, int t) {
        int start = 0, end = 0, ans;

        // Compute the total time and the maximum
        // job duration  
        foreach (int j in job) {
            
            // Total sum of job times
            end += j; 
            
            // Maximum job duration
            start = Math.Max(start, j);    
        }
        
        // Initialize answer to the upper bound 
        ans = end;   

        // Perform binary search to find the minimum
        // feasible time  
        while (start <= end) {
            int mid = (start + end) / 2;

            // If jobs can be assigned within 'mid' time  
            if (IsPossible(job, mid, k)) {
                ans = Math.Min(ans, mid);  
                end = mid - 1;  
            } else {
                start = mid + 1;  
            }
        }

        // Return the minimum time required  
        return ans * t;
    }

    public static void Main() {
        int[] job = {10, 7, 8, 12, 6, 8};
        int k = 4, t = 5;
        
        Console.WriteLine(FindMinTime(job, k, t));
    }
}
JavaScript
// JavaScript program to find the minimum time required  
// to finish all jobs using Binary Search  

// Function to find the maximum job duration  
function GetMax(job) {  
    let res = job[0];  

    // Find the maximum time among all jobs  
    for (let i = 1; i < job.length; i++) {  
        if (job[i] > res) {  
            res = job[i];  
        }  
    }  
    return res;  
}  

// Function to check if jobs can be completed within  
// 't' time using at most 'k' assignees  
function IsPossible(job, t, k) {  

    // Number of assignees required  
    let cnt = 1;  

    // Time assigned to the current assignee  
    let curr = 0;  

    let i = 0;
    while (i < job.length) {  

        // If adding the current job exceeds 't',
        // assign a new assignee  
        if (curr + job[i] > t) {  
            curr = 0;  
            cnt++;  
        } else {  

            // Otherwise, add job time to the  
            // current assignee  
            curr += job[i];  
            i++;  
        }  
    }  

    return cnt <= k;  
}  

// Function to find the minimum time required to  
// finish all jobs  
function FindMinTime(job, k, t) {  
    let start = 0, end = 0;  

    // Compute the total time and the maximum  
    // job duration  
    for (let j of job) {  

        // Total sum of job times  
        end += j;  

        // Maximum job duration  
        start = Math.max(start, j);  
    }  

    // Initialize answer to the upper bound  
    let ans = end;  

    // Perform binary search to find the minimum  
    // feasible time  
    while (start <= end) {  
        let mid = Math.floor((start + end) / 2);  

        // If jobs can be assigned within 'mid' time  
        if (IsPossible(job, mid, k)) {  
            ans = Math.min(ans, mid);  
            end = mid - 1;  
        } else {  
            start = mid + 1;  
        }  
    }  

    // Return the minimum time required  
    return ans * t;  
}  

// Driver Code
let job = [10, 7, 8, 12, 6, 8];  
let k = 4, t = 5;  

console.log(FindMinTime(job, k, t));  

Output: 

75

Time Complexity: O(n log(sum(job))) due to binary search over the time range and checking feasibility in O(n). 
Space Complexity: O(1) as only a few integer variables are used, and no extra data structures are allocated.


Next Article
Article Tags :
Practice Tags :

Similar Reads