Minimum time required to schedule K processes

13 Jul, 2021
Given a positive integer K and an array arr[] consisting of N positive integers, such that arr[i] is the number of processes ith processor can schedule in 1 second. The task is to minimize the total time required to schedule K processes such that after scheduling by the ith processor, arr[i] is reduced to floor(arr[i]/2).
Examples:
Input: N = 5, arr[] = {3, 1, 7, 2, 4}, K = 15Output: 4Explanation:The order of scheduled process are as follows:
The 3rd process is scheduled first. The array arr[] modifies to {3, 1, 3, 2, 4}, as arr[2] = floor(arr[2] / 2) = floor(7 / 2) = 3.The 5th process is scheduled next. The array arr[] modifies to {3, 1, 3, 2, 2}.The 1st process is scheduled next. The array arr[] modifies to {1, 1, 3, 2, 2}.The 2nd process is scheduled next. The array arr[] modifies to {3, 0, 3, 2, 4}.
The 3rd process is scheduled first. The array arr[] modifies to {3, 1, 3, 2, 4}, as arr[2] = floor(arr[2] / 2) = floor(7 / 2) = 3.
The 5th process is scheduled next. The array arr[] modifies to {3, 1, 3, 2, 2}.
The 1st process is scheduled next. The array arr[] modifies to {1, 1, 3, 2, 2}.
The 2nd process is scheduled next. The array arr[] modifies to {3, 0, 3, 2, 4}.
The total processes scheduled by all the process = 7 + 4 + 3 + 1 = 15(= K) and the total time required is 4 seconds.
Input: N = 4, arr[] = {1, 5, 8, 6}, K = 10Output: 2
Naive Approach: The simplest approach to solve the given problem is to sort the given list in ascending order and choose the processor with the highest ability and reduce the value of K by that value and delete that processor from the list and add half of that in the sorted list again. Repeat the above process until at least K processes are scheduled and print the time required after scheduling at least K processes.
Time Complexity: O(N*log N)Auxiliary Space: O(N)
Efficient Approach: The above approach can also be optimized by using the concept of Hashing. Follow the below steps to solve the problem:
Initialize an auxiliary array tmp[] of the size of the maximum element present in the given array.
Initialize a variable, say count to store the minimum time to schedule all processes respectively.
Traverse the given array tmp[] from the end and perform the following steps:If the current element in tmp[] is greater than 0 and i * tmp[i] is smaller than K.Decrease the value of K by the value i * tmp[i].Increase tmp[i/2] by tmp[i] as the ability of the processor will decrease by half.Increase the value of count by the value tmp[i].If the value of K is already smaller than or equal to 0, then print the value of count as the result.If the current element in the array tmp[] is at least 0 and the value of i * tmp[i] is at least K, then perform the following steps:If K is divisible by the current index, then increment the value of count by K / i.Otherwise, increment the value of count by K/i +1.
If the current element in tmp[] is greater than 0 and i * tmp[i] is smaller than K.Decrease the value of K by the value i * tmp[i].Increase tmp[i/2] by tmp[i] as the ability of the processor will decrease by half.Increase the value of count by the value tmp[i].If the value of K is already smaller than or equal to 0, then print the value of count as the result.
Decrease the value of K by the value i * tmp[i].
Increase tmp[i/2] by tmp[i] as the ability of the processor will decrease by half.
Increase the value of count by the value tmp[i].
If the value of K is already smaller than or equal to 0, then print the value of count as the result.
If the current element in the array tmp[] is at least 0 and the value of i * tmp[i] is at least K, then perform the following steps:If K is divisible by the current index, then increment the value of count by K / i.Otherwise, increment the value of count by K/i +1.
If K is divisible by the current index, then increment the value of count by K / i.
Otherwise, increment the value of count by K/i +1.
After completing the above steps, print -1 if it is not possible to schedule all processes. Otherwise, print the count as the minimum time required.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // Function to find minimum required// time to schedule all processint minTime(int A[], int n, int K){         // Stores max element from A[]    int max_ability = A[0];     // Find the maximum element    for(int i = 1; i < n; i++)    {        max_ability = max(max_ability, A[i]);    }     // Stores frequency of each element    int tmp[max_ability + 1] = {0};     // Stores minimum time required    // to schedule all process    int count = 0;     // Count frequencies of elements    for(int i = 0; i < n; i++)    {        tmp[A[i]]++;    }     // Find the minimum time    for(int i = max_ability; i >= 0; i--)    {        if (tmp[i] != 0)        {            if (tmp[i] * i < K)            {                                 // Decrease the value                // of K                K -= (i * tmp[i]);                 // Increment tmp[i/2]                tmp[i / 2] += tmp[i];                 // Increment the count                count += tmp[i];                 // Return count, if all                // process are scheduled                if (K <= 0)                {                    return count;                }            }             else            {                                 // Increment count                if (K % i != 0)                {                    count += (K / i) + 1;                }                else                {                    count += (K / i);                }                 // Return the count                return count;            }        }    }     // If it is not possible to    // schedule all process    return -1;} // Driver codeint main(){    int arr[] = { 3, 1, 7, 2, 4 };    int N = 5;    int K = 15;         cout << minTime(arr, N, K);         return 0;} // This code is contributed by mohit kumar 29
// Java program for the above approach import java.util.*;import java.lang.*; class GFG {     // Function to find minimum required    // time to schedule all process    static int minTime(int[] A, int n, int K)    {        // Stores max element from A[]        int max_ability = A[0];         // Find the maximum element        for (int i = 1; i < n; i++) {            max_ability = Math.max(                max_ability, A[i]);        }         // Stores frequency of each element        int tmp[] = new int[max_ability + 1];         // Stores minimum time required        // to schedule all process        int count = 0;         // Count frequencies of elements        for (int i = 0; i < n; i++) {            tmp[A[i]]++;        }         // Find the minimum time        for (int i = max_ability;             i >= 0; i--) {             if (tmp[i] != 0) {                 if (tmp[i] * i < K) {                     // Decrease the value                    // of K                    K -= (i * tmp[i]);                     // Increment tmp[i/2]                    tmp[i / 2] += tmp[i];                     // Increment the count                    count += tmp[i];                     // Return count, if all                    // process are scheduled                    if (K <= 0) {                        return count;                    }                }                 else {                     // Increment count                    if (K % i != 0) {                        count += (K / i) + 1;                    }                    else {                        count += (K / i);                    }                     // Return the count                    return count;                }            }        }         // If it is not possible to        // schedule all process        return -1;    }     // Driver Code    public static void main(String[] args)    {        int arr[] = { 3, 1, 7, 2, 4 };        int N = arr.length;        int K = 15;        System.out.println(            minTime(arr, N, K));    }}
# Python3 program for the above approach # Function to find minimum required# time to schedule all processdef minTime(A, n, K):         # Stores max element from A[]    max_ability = A[0]     # Find the maximum element    for i in range(1, n):        max_ability = max(max_ability, A[i])     # Stores frequency of each element    tmp = [0 for i in range(max_ability + 1)]     # Stores minimum time required    # to schedule all process    count = 0     # Count frequencies of elements    for i in range(n):        tmp[A[i]] += 1     # Find the minimum time    i = max_ability         while(i >= 0):        if (tmp[i] != 0):            if (tmp[i] * i < K):                                 # Decrease the value                # of K                K -= (i * tmp[i])                 # Increment tmp[i/2]                tmp[i // 2] += tmp[i]                 # Increment the count                count += tmp[i]                 # Return count, if all                # process are scheduled                if (K <= 0):                    return count            else:                                 # Increment count                if (K % i != 0):                    count += (K // i) + 1                else:                    count += (K // i)                 # Return the count                return count        i -= 1     # If it is not possible to    # schedule all process    return -1 # Driver codeif __name__ == '__main__':         arr = [ 3, 1, 7, 2, 4 ]    N = 5    K = 15         print(minTime(arr, N, K)) # This code is contributed by SURENDRA_GANGWAR
// C# program for the above approachusing System; class GFG{ // Function to find minimum required// time to schedule all processstatic int minTime(int[] A, int n, int K){         // Stores max element from A[]    int max_ability = A[0];     // Find the maximum element    for(int i = 1; i < n; i++)    {        max_ability = Math.Max(            max_ability, A[i]);    }     // Stores frequency of each element    int []tmp = new int[max_ability + 1];     // Stores minimum time required    // to schedule all process    int count = 0;     // Count frequencies of elements    for(int i = 0; i < n; i++)    {        tmp[A[i]]++;    }         // Find the minimum time    for(int i = max_ability; i >= 0; i--)    {        if (tmp[i] != 0)        {            if (tmp[i] * i < K)            {                                 // Decrease the value                // of K                K -= (i * tmp[i]);                 // Increment tmp[i/2]                tmp[i / 2] += tmp[i];                 // Increment the count                count += tmp[i];                 // Return count, if all                // process are scheduled                if (K <= 0)                {                    return count;                }            }             else            {                                 // Increment count                if (K % i != 0)                {                    count += (K / i) + 1;                }                else                {                    count += (K / i);                }                 // Return the count                return count;            }        }    }     // If it is not possible to    // schedule all process    return -1;} // Driver Codepublic static void Main(string[] args){    int []arr = { 3, 1, 7, 2, 4 };    int N = arr.Length;    int K = 15;         Console.WriteLine(minTime(arr, N, K));}} // This code is contributed by ukasp
<script> // JavaScript Program to implement// the above approach     // Function to find minimum required    // time to schedule all process    function minTime(A, n, K)    {        // Stores max element from A[]        let max_ability = A[0];          // Find the maximum element        for (let i = 1; i < n; i++) {            max_ability = Math.max(                max_ability, A[i]);        }          // Stores frequency of each element        let tmp =        Array.from({length: max_ability + 1}, (_, i) => 0);          // Stores minimum time required        // to schedule all process        let count = 0;          // Count frequencies of elements        for (let i = 0; i < n; i++) {            tmp[A[i]]++;        }          // Find the minimum time        for (let i = max_ability;             i >= 0; i--) {              if (tmp[i] != 0) {                  if (tmp[i] * i < K) {                      // Decrease the value                    // of K                    K -= (i * tmp[i]);                      // Increment tmp[i/2]                    tmp[(i / 2)] += tmp[i];                      // Increment the count                    count += tmp[i];                      // Return count, if all                    // process are scheduled                    if (K <= 0) {                        return count;                    }                }                  else {                      // Increment count                    if (K % i != 0) {                        count += Math.floor(K / i) + 1;                    }                    else {                        count += Math.floor(K / i);                    }                      // Return the count                    return count;                }            }        }          // If it is not possible to        // schedule all process        return -1;    } // Driver Code      let arr = [ 3, 1, 7, 2, 4 ];     let N = arr.length;     let K = 15;     document.write( minTime(arr, N, K)); </script>
4
Time Complexity: O(M), where M is the maximum element in the array.Auxiliary Space: O(M)
Alternative Approach(Using STL): The given problem can be solved by using the Greedy Approach with the help of max-heap. Follow the steps below to solve the problem:
Initialize a priority queue, say PQ, and insert all the elements of the given array into PQ.
Initialize a variable, say ans as 0 to store the resultant maximum diamond gained.
Iterate a loop until the priority queue PQ is not empty and the value of K > 0:Pop the top element of the priority queue and add the popped element to the variable ans.Divide the popped element by 2 and insert it into the priority queue PQ.Decrement the value of K by 1.
Pop the top element of the priority queue and add the popped element to the variable ans.
Divide the popped element by 2 and insert it into the priority queue PQ.
Decrement the value of K by 1.
After completing the above steps, print the value of ans as the result.
Below is the implementation of the above approach:
C++14
Python3
Javascript
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // Function to execute k processes that can be gained in// minimum amount of timevoid executeProcesses(int A[], int N, int K){    // Stores all the array elements    priority_queue<int> pq;     // Push all the elements to the    // priority queue    for (int i = 0; i < N; i++) {        pq.push(A[i]);    }     // Stores the required result    int ans = 0;     // Loop while the queue is not    // empty and K is positive    while (!pq.empty() && K > 0) {         // Store the top element        // from the pq        int top = pq.top();         // Pop it from the pq        pq.pop();         // Add it to the answer        ans ++;         // Divide it by 2 and push it        // back to the pq        K = K - top;        top = top / 2;        pq.push(top);    }     // Print the answer    cout << ans;} // Driver Codeint main(){    int A[] = { 3, 1, 7, 4, 2 };    int K = 15;    int N = sizeof(A) / sizeof(A[0]);    executeProcesses(A, N, K);     return 0;}
# Python3 program for the above approach  # Function to execute k processes that# can be gained in minimum amount of timedef executeProcesses(A, N, K):         # Stores all the array elements    pq = []         # Push all the elements to the    # priority queue    for i in range(N):        pq.append(A[i])         # Stores the required result    ans = 0    pq.sort()         # Loop while the queue is not    # empty and K is positive    while (len(pq) > 0 and K > 0):                 # Store the top element        # from the pq        top = pq.pop()                 # Add it to the answer        ans += 1                 # Divide it by 2 and push it        # back to the pq        K -= top        top //=2        pq.append(top)                 pq.sort()         # Print the answer    print(ans) # Driver CodeA = [ 3, 1, 7, 4, 2 ]K = 15N=len(A)executeProcesses(A, N, K) #  This code is contributed by patel2127
<script> // Javascript program for the above approach // Function to execute k processes that// can be gained in minimum amount of timefunction executeProcesses(A, N, K){         // Stores all the array elements    let pq = [];         // Push all the elements to the    // priority queue    for(let i = 0; i < N; i++)    {        pq.push(A[i]);    }      // Stores the required result    let ans = 0;     pq.sort(function(a, b){return a - b;});          // Loop while the queue is not    // empty and K is positive    while (pq.length > 0 && K > 0)    {                 // Store the top element        // from the pq        let top = pq.pop();              // Add it to the answer        ans++;          // Divide it by 2 and push it        // back to the pq        K -= top;        top = Math.floor(top / 2);        pq.push(top);                 pq.sort(function(a, b){return a - b;});    }         // Print the answer    document.write(ans)} // Driver Codelet A = [ 3, 1, 7, 4, 2 ];let K = 15;let N = A.length; executeProcesses(A, N, K); // This code is contributed by avanitrachhadiya2155 </script>
4
Time Complexity: O((N + K)*log N)
Auxiliary Space: O(N)
mohit kumar 29
ukasp
sanjoy_62
SURENDRA_GANGWAR
Ask149
avanitrachhadiya2155
patel2127
arorakashish0911
Amazon
Amazon-Question
interview-preparation
Arrays
Hash
Heap
Mathematical
Amazon
Arrays
Hash
Mathematical
Heap
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.