 GeeksforGeeks App
Open App Browser
Continue

# 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 1

Input: 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 ``using` `namespace` `std;` `// Function to calculate``// the minimum work sessions``int` `minSessions(vector<``int``>& codeTime,``                ``vector >& 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 > 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

 ``

Output:

`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.

My Personal Notes arrow_drop_up