调试所有程序的最少天数
给定数组codeTime和整数WorkingSessionTime中的N个程序代码及其各自的调试时间,第i个程序需要codeTime[i]小时才能完成。 WorkingSessionTime定义了一个阈值时间,您最多连续工作几个小时 WorkingSessionTime 然后休息一下。如果 WorkingSessionTime小于6 小时,则 每天可以参加 2 次工作会议,否则每天只能参加 1 次工作会议。
调试应在以下条件下完成:
- 一个调试序列应该在同一个会话中完成(以任何顺序)。
- 完成上一个调试任务后,可以立即开始新的调试任务。
任务是打印在上述条件下调试所有程序所需的最少天数。假设WorkingSessionTime大于或等于codeTime数组中的最大元素。
例子:
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
方法:一个简单的解决方案是尝试所有可能的任务顺序。首先从数组中选择第一个元素,将其标记为已访问并递归剩余任务并找出所有可能的订单中的最小会话它基本上是一个基于回溯的解决方案。在找到最小会话数后,我们将检查会话的工作时间是否少于 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 表的大小。