Minimum number of days to debug all programs
Given N program codes and their respective debugging times in an array codeTime and an integer WorkingSessionTime, the ith program takes codeTime[i] hours to finish. WorkingSessionTime defines a threshold time, you work for at most WorkingSessionTime consecutive hours and then take a break. If WorkingSessionTime is less than 6 hours then 2 working sessions per day can be taken else only one working session per day can be taken.
Debugging should be finished following the below conditions:
- One debugging sequence should be completed in the same session (in any order).
- The new debugging task can be started immediately after finishing the previous one.
The task is to print the minimum number of days needed to debug all the programs following the conditions above. Assume that WorkingSessionTime is greater than or equal to the maximum element in codeTime array.
Examples :
Input: codeTime[] = {1, 2, 3}, WorkingSessionTime = 3
Output: 1
Explanation: In first work session we will finish first and second task in 1+2 = 3 hours and we can finish last task in second work session, so the total 2 work session required to finish the task. WorkingSessionTime is less than 6 so we can take two session per day so minimum number of days will be 1Input: codeTime [] = {1, 2, 3, 1, 1, 3}, WorkingSessionTime = 4
Output: 2
Explanation : In first work session we will finish first and third task in 1+3 = 4 hours and in second session we can finish fourth and sixth tasks in 1+3 = 4 hours and in third session we can finish second and fifth tasks 2 + 1 = 3 hours. WorkingSessionTime is less than 6 so we can take two session per day . On first day we will take two working sessions and on next day we will take one working session. So minimum number of days required is 2
Approach: A simple solution is to try all possible orders of tasks. Start by picking the first element from the array, marking it as visited and recurse for remaining tasks and find out minimum sessions among all possible orders It is basically a backtracking based solution. After finding a minimum number of sessions we will check if the working hours of the session are less than 6 or not. If it is less than 6 then we will further check no of the minimum sessions are even or odd.
Optimal Approach: A better solution is to use Bitmasking and DP
The idea is to use the fact that there are up to 14 tasks, So we can use a integer variable as mask to denote which elements are processed. if the ith bit is off, it means the ith task is yet to be processed with the remaining time we have for the current session. If the ith bit is set, it means the ith program code debugging task is processed.
- Initialize mask as 000…000, which represents the initial (unprocessed) states of all elements.
- Pass remaining time as 0, which means there is no remaining time for the current session and we have to create a new session.
- Check if the ith bit is processed or not, make calls if the task is unprocessed. if ith program code debugging task is unprocessed, mark it as processed.
- If the remaining time is greater than the codeTime[i], we will include ith program code debugging task in the current session and update the remaining time, else we have to create new session and increase the number of sessions by 1.
- Once all the elements are processed or the mask becomes 1, we will get the minimum possible sessions.
- If working session time is less than 6, we will further check a minimum number of possible sessions is even or odd if it even a minimum number of days will be half of the minimum number of sessions and if it is the odd minimum number of days half of the minimum number of sessions +1, else a minimum number of days will be equal to answer.
To deal with the overlapping subproblems, create a 2D DP table to store the answers for subproblems. For every element dp[i][j], i is the mask and j is the remaining time.
Below is the implementation of the above approach:
C++14
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to calculate // the minimum work sessions int minSessions(vector< int >& codeTime, vector<vector< int > >& dp, int ones, int n, int mask, int currTime, int WorkingSessionTime) { // Break condition if (currTime > WorkingSessionTime) return INT_MAX; // All bits are set if (mask == ones) return 1; // Check if already calculated if (dp[mask][currTime] != -1) return dp[mask][currTime]; // Store the answer int ans = INT_MAX; for ( int i = 0; i < n; i++) { // Check if ith bit is set or unset if ((mask & (1 << i)) == 0) { // Including in current work session int inc = minSessions( codeTime, dp, ones, n, mask | (1 << i), currTime + codeTime[i], WorkingSessionTime); // Including in next work session int inc_next = 1 + minSessions( codeTime, dp, ones, n, mask | (1 << i), codeTime[i], WorkingSessionTime); // Resultant answer will be minimum of both ans = min({ ans, inc, inc_next }); } } return dp[mask][currTime] = ans; } // Function to initialize DP array // and solve the problem int solve(vector< int > codeTime, int n, int WorkingSessionTime) { // Initialize dp table with -1 vector<vector< int > > dp((1 << 14), vector< int >(15, -1)); // Resultant mask int ones = (1 << n) - 1; int ans = minSessions(codeTime, dp, ones, n, 0, 0, WorkingSessionTime); // no. of minimum work sessions is even if (WorkingSessionTime < 6) { if (ans % 2 == 0) ans = ans / 2; // no. of minimum work sessions is odd else ans = (ans / 2) + 1; } return ans; } // Driver code int main() { vector< int > codeTime = { 1, 2, 3, 1, 1, 3 }; int n = codeTime.size(); int WorkingSessionTime = 4; cout << solve(codeTime, n, WorkingSessionTime) << endl; return 0; } |
Java
// Java program for the above approach import java.util.Arrays; class GFG { // Function to calculate // the minimum work sessions public static int minSessions( int [] codeTime, int [][] dp, int ones, int n, int mask, int currTime, int WorkingSessionTime) { // Break condition if (currTime > WorkingSessionTime) return Integer.MAX_VALUE; // All bits are set if (mask == ones) return 1 ; // Check if already calculated if (dp[mask][currTime] != - 1 ) return dp[mask][currTime]; // Store the answer int ans = Integer.MAX_VALUE; for ( int i = 0 ; i < n; i++) { // Check if ith bit is set or unset if ((mask & ( 1 << i)) == 0 ) { // Including in current work session int inc = minSessions(codeTime, dp, ones, n, mask | ( 1 << i), currTime + codeTime[i], WorkingSessionTime); // Including in next work session int inc_next = 1 + minSessions(codeTime, dp, ones, n, mask | ( 1 << i), codeTime[i], WorkingSessionTime); // Resultant answer will be minimum of both ans = Math.min(ans, Math.min(inc, inc_next)); } } return dp[mask][currTime] = ans; } // Function to initialize DP array // and solve the problem public static int solve( int [] codeTime, int n, int WorkingSessionTime) { // Initialize dp table with -1 int [][] dp = new int [( 1 << 14 )][]; for ( int i = 0 ; i < 1 << 14 ; i++) { dp[i] = new int [ 15 ]; Arrays.fill(dp[i], - 1 ); } // Resultant mask int ones = ( 1 << n) - 1 ; int ans = minSessions(codeTime, dp, ones, n, 0 , 0 , WorkingSessionTime); // no. of minimum work sessions is even if (WorkingSessionTime < 6 ) { if (ans % 2 == 0 ) ans = ans / 2 ; // no. of minimum work sessions is odd else ans = (ans / 2 ) + 1 ; } return ans; } // Driver code public static void main(String args[]) { int [] codeTime = { 1 , 2 , 3 , 1 , 1 , 3 }; int n = codeTime.length; int WorkingSessionTime = 4 ; System.out.println(solve(codeTime, n, WorkingSessionTime)); } } // This code is contributed by saurabh_jaiswal. |
Python3
# Python 3 program for the above approach import sys # Function to calculate # the minimum work sessions def minSessions(codeTime, dp, ones, n, mask, currTime, WorkingSessionTime): # Break condition if (currTime > WorkingSessionTime): return sys.maxsize # All bits are set if (mask = = ones): return 1 # Check if already calculated if (dp[mask][currTime] ! = - 1 ): return dp[mask][currTime] # Store the answer ans = sys.maxsize for i in range (n): # Check if ith bit is set or unset if ((mask & ( 1 << i)) = = 0 ): # Including in current work session inc = minSessions(codeTime, dp, ones, n, mask | ( 1 << i),currTime + codeTime[i],WorkingSessionTime) # Including in next work session inc_next = 1 + minSessions(codeTime, dp, ones, n,mask | ( 1 << i), codeTime[i],WorkingSessionTime) # Resultant answer will be minimum of both ans = min ([ans, inc, inc_next]) dp[mask][currTime] = ans return ans # Function to initialize DP array # and solve the problem def solve(codeTime, n, WorkingSessionTime): # Initialize dp table with -1 dp = [[ - 1 for i in range ( 15 )] for j in range ( 1 << 14 )] # Resultant mask ones = ( 1 << n) - 1 ans = minSessions(codeTime, dp, ones, n, 0 , 0 , WorkingSessionTime) # no. of minimum work sessions is even if (WorkingSessionTime < 6 ): if (ans % 2 = = 0 ): ans = ans / / 2 # no. of minimum work sessions is odd else : ans = (ans / 2 ) + 1 return int (ans) # Driver code if __name__ = = '__main__' : codeTime = [ 1 , 2 , 3 , 1 , 1 , 3 ] n = len (codeTime) WorkingSessionTime = 4 print (solve(codeTime, n, WorkingSessionTime)) # This code is contributed by SURENDRA_GANGWAR. |
C#
// C# program for the above approach using System; public class GFG { // Function to calculate // the minimum work sessions public static int minSessions( int [] codeTime, int [, ] dp, int ones, int n, int mask, int currTime, int WorkingSessionTime) { // Break condition if (currTime > WorkingSessionTime) return Int32.MaxValue; // All bits are set if (mask == ones) return 1; // Check if already calculated if (dp[mask, currTime] != -1) return dp[mask, currTime]; // Store the answer int ans = Int32.MaxValue; for ( int i = 0; i < n; i++) { // Check if ith bit is set or unset if ((mask & (1 << i)) == 0) { // Including in current work session int inc = minSessions(codeTime, dp, ones, n, mask | (1 << i), currTime + codeTime[i], WorkingSessionTime); // Including in next work session int inc_next = 1 + minSessions(codeTime, dp, ones, n, mask | (1 << i), codeTime[i], WorkingSessionTime); // Resultant answer will be minimum of both ans = Math.Min(ans, Math.Min(inc, inc_next)); } } return dp[mask, currTime] = ans; } // Function to initialize DP array // and solve the problem public static int solve( int [] codeTime, int n, int WorkingSessionTime) { // Initialize dp table with -1 int [, ] dp = new int [(1 << 14), 15]; for ( int i = 0; i < 1 << 14; i++) { for ( int j = 0; j < 15; j++) { dp[i, j] = -1; } } // Resultant mask int ones = (1 << n) - 1; int ans = minSessions(codeTime, dp, ones, n, 0, 0, WorkingSessionTime); // no. of minimum work sessions is even if (WorkingSessionTime < 6) { if (ans % 2 == 0) ans = ans / 2; // no. of minimum work sessions is odd else ans = (ans / 2) + 1; } return ans; } // Driver code static public void Main (){ int [] codeTime = { 1, 2, 3, 1, 1, 3 }; int n = codeTime.Length; int WorkingSessionTime = 4; Console.WriteLine(solve(codeTime, n, WorkingSessionTime)); } } // This code is contributed by Dharanendra L V. |
Javascript
<script> // JavaScript Program to implement // the above approach // Function to calculate // the minimum work sessions function minSessions(codeTime, dp, ones, n, mask, currTime, WorkingSessionTime) { // Break condition if (currTime > WorkingSessionTime) return Number.MAX_VALUE; // All bits are set if (mask == ones) return 1; // Check if already calculated if (dp[mask][currTime] != -1) return dp[mask][currTime]; // Store the answer let ans = Number.MAX_VALUE; for (let i = 0; i < n; i++) { // Check if ith bit is set or unset if ((mask & (1 << i)) == 0) { // Including in current work session let inc = minSessions( codeTime, dp, ones, n, mask | (1 << i), currTime + codeTime[i], WorkingSessionTime); // Including in next work session let inc_next = 1 + minSessions( codeTime, dp, ones, n, mask | (1 << i), codeTime[i], WorkingSessionTime); // Resultant answer will be minimum of both ans = Math.min(ans, Math.min(inc, inc_next)); } } return dp[mask][currTime] = ans; } // Function to initialize DP array // and solve the problem function solve(codeTime, n, WorkingSessionTime) { // Initialize dp table with -1 let dp = new Array(1 << 14); for (let i = 0; i < dp.length; i++) { dp[i] = new Array(15).fill(-1); } // Resultant mask let ones = (1 << n) - 1; let ans = minSessions(codeTime, dp, ones, n, 0, 0, WorkingSessionTime); // no. of minimum work sessions is even if (WorkingSessionTime < 6) { if (ans % 2 == 0) ans = Math.floor(ans / 2); // no. of minimum work sessions is odd else ans = Math.floor(ans / 2) + 1; } return ans; } // Driver code let codeTime = [1, 2, 3, 1, 1, 3]; let n = codeTime.length; let WorkingSessionTime = 4; document.write( solve(codeTime, n, WorkingSessionTime)) // This code is contributed by Potta Lokesh </script> |
2
Time Complexity: O(2^N * WorkingSessionTime * N), Here N is the length of array codeTime.
Auxiliary Space: O(2^N * WorkingSessionTime), size of the dp table.
Please Login to comment...