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++
#include<bits/stdc++.h>
using namespace std;
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;
}
bool isPossible( int time , int K, int job[], int n)
{
int cnt = 1;
int curr_time = 0;
for ( int i = 0; i < n;)
{
if (curr_time + job[i] > time ) {
curr_time = 0;
cnt++;
}
else {
curr_time += job[i];
i++;
}
}
return (cnt <= K);
}
int findMinTime( int K, int T, int job[], int n)
{
int end = 0, start = 0;
for ( int i = 0; i < n; ++i)
end += job[i];
int ans = end;
int job_max = getMax(job, n);
while (start <= end)
{
int mid = (start + end) / 2;
if (mid >= job_max && isPossible(mid, K, job, n))
{
ans = min(ans, mid);
end = mid - 1;
}
else
start = mid + 1;
}
return (ans * T);
}
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
class GFG
{
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;
}
static boolean isPossible( int time, int K,
int job[], int n)
{
int cnt = 1 ;
int curr_time = 0 ;
for ( int i = 0 ; i < n;)
{
if (curr_time + job[i] > time) {
curr_time = 0 ;
cnt++;
}
else
{
curr_time += job[i];
i++;
}
}
return (cnt <= K);
}
static int findMinTime( int K, int T, int job[], int n)
{
int end = 0 , start = 0 ;
for ( int i = 0 ; i < n; ++i)
end += job[i];
int ans = end;
int job_max = getMax(job, n);
while (start <= end)
{
int mid = (start + end) / 2 ;
if (mid >= job_max && isPossible(mid, K, job, n))
{
ans = Math.min(ans, mid);
end = mid - 1 ;
}
else
start = mid + 1 ;
}
return (ans * T);
}
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));
}
}
|
Python3
def getMax(arr, n):
result = arr[ 0 ]
for i in range ( 1 , n):
if arr[i] > result:
result = arr[i]
return result
def isPossible(time, K, job, n):
cnt = 1
curr_time = 0
i = 0
while i < n:
if curr_time + job[i] > time:
curr_time = 0
cnt + = 1
else :
curr_time + = job[i]
i + = 1
return cnt < = K
def findMinTime(K, T, job, n):
end = 0
start = 0
for i in range (n):
end + = job[i]
ans = end
job_max = getMax(job, n)
while start < = end:
mid = int ((start + end) / 2 )
if mid > = job_max and isPossible(mid, K, job, n):
ans = min (ans, mid)
end = mid - 1
else :
start = mid + 1
return ans * T
if __name__ = = '__main__' :
job = [ 10 , 7 , 8 , 12 , 6 , 8 ]
n = len (job)
k = 4
T = 5
print (findMinTime(k, T, job, n))
|
C#
using System;
class GFG
{
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;
}
static bool isPossible( int time, int K,
int []job, int n)
{
int cnt = 1;
int curr_time = 0;
for ( int i = 0; i < n;)
{
if (curr_time + job[i] > time) {
curr_time = 0;
cnt++;
}
else
{
curr_time += job[i];
i++;
}
}
return (cnt <= K);
}
static int findMinTime( int K, int T, int []job, int n)
{
int end = 0, start = 0;
for ( int i = 0; i < n; ++i)
end += job[i];
int ans = end;
int job_max = getMax(job, n);
while (start <= end)
{
int mid = (start + end) / 2;
if (mid >= job_max && isPossible(mid, K, job, n))
{
ans = Math.Min(ans, mid);
end = mid - 1;
}
else
start = mid + 1;
}
return (ans * T);
}
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));
}
}
|
Javascript
<script>
function getMax(arr, n)
{
let result = arr[0];
for (let i=1; i<n; i++)
if (arr[i] > result)
result = arr[i];
return result;
}
function isPossible(time, K, job, n)
{
let cnt = 1;
let curr_time = 0;
for (let i = 0; i < n;)
{
if (curr_time + job[i] > time) {
curr_time = 0;
cnt++;
}
else
{
curr_time += job[i];
i++;
}
}
return (cnt <= K);
}
function findMinTime(K, T, job, n)
{
let end = 0, start = 0;
for (let i = 0; i < n; ++i)
end += job[i];
let ans = end;
let job_max = getMax(job, n);
while (start <= end)
{
let mid = parseInt((start + end) / 2, 10);
if (mid >= job_max && isPossible(mid, K, job, n))
{
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.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above