📜  调试所有程序的最少天数

📅  最后修改于: 2022-05-13 01:56:04.306000             🧑  作者: Mango

调试所有程序的最少天数

给定数组codeTime和整数WorkingSessionTime中的N个程序代码及其各自的调试时间,第i个程序需要codeTime[i]小时才能完成。 WorkingSessionTime定义了一个阈值时间,您最多连续工作几个小时 WorkingSessionTime 然后休息一下。如果 WorkingSessionTime小于6 小时,则 每天可以参加 2 次工作会议,否则每天只能参加 1 次工作会议。

调试应在以下条件下完成:

  • 一个调试序列应该在同一个会话中完成(以任何顺序)。
  • 完成上一个调试任务后,可以立即开始新的调试任务。

任务是打印在上述条件下调试所有程序所需的最少天数。假设WorkingSessionTime大于或等于codeTime数组中的最大元素。  

例子

方法:一个简单的解决方案是尝试所有可能的任务顺序。首先从数组中选择第一个元素,将其标记为已访问并递归剩余任务并找出所有可能的订单中的最小会话它基本上是一个基于回溯的解决方案。在找到最小会话数后,我们将检查会话的工作时间是否少于 6 小时。如果小于 6,那么我们将进一步检查最小会话数是偶数还是奇数。

最佳方法:更好的解决方案是使用 位掩码和 DP

这个想法是利用最多有 14 个任务的事实,所以我们可以使用一个整数变量作为掩码来表示哪些元素被处理。如果第 i 位为off ,则表示第 i 个任务尚未处理,剩余时间为我们当前会话的剩余时间。如果第 i 位被位,则表示第 i 个程序代码调试任务被处理。

  • 将掩码初始化为 000…000,表示所有元素的初始(未处理)状态。
  • 将剩余时间传递为 0,这意味着当前会话没有剩余时间,我们必须创建一个新会话。
  • 检查第 i 位是否被处理,如果任务未处理则调用。如果第i个程序代码调试任务未处理,则标记为已处理。
  • 如果剩余时间大于codeTime[i],我们将第i个程序代码调试任务包含在当前会话中并更新剩余时间,否则我们必须创建新会话并将会话数增加1。
  • 一旦处理完所有元素或掩码变为 1,我们将获得尽可能少的会话。
  • 如果工作会话时间少于6 个,我们将进一步检查可能的最小会话数是偶数还是奇数,如果是偶数,最小天数将是最小会话数的一半,如果是奇数最小天数最少会话数的一半+1,否则最少天数将等于回答。

要处理重叠的子问题,请创建一个 2D DP 表来存储子问题的答案。对于每个元素 dp[i][j], i是掩码, j是剩余时间。

下面是上述方法的实现:

C++14
// C++ program for the above approach
#include 
using namespace std;
 
// Function to calculate
// the minimum work sessions
int minSessions(vector& 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 codeTime, int n,
          int WorkingSessionTime)
{
 
    // Initialize dp table with -1
    vector > dp((1 << 14),
                            vector(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 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


输出:
2

时间复杂度:O(2^N * WorkingSessionTime * N),这里N是数组codeTime的长度。
辅助空间:O(2^N * WorkingSessionTime),dp 表的大小。