完成任务的最少工作时间段
难度:
标签:
题目描述
代码结果
运行时间: 36 ms, 内存: 16.0 MB
/*
* 思路:
* 1. 使用位掩码表示任务的组合,dp[i]表示完成任务集合i所需的最小工作时间段数。
* 2. 使用动态规划方法计算每种任务组合所需的最小工作时间段数。
* 3. 对于每个任务组合i,尝试将一个新任务加入,更新最小工作时间段数。
* 4. 使用Java Stream处理任务组合。
*/
import java.util.*;
import java.util.stream.*;
public class MinSessionsStream {
public int minSessions(int[] tasks, int sessionTime) {
int n = tasks.length;
int[] dp = new int[1 << n];
Arrays.fill(dp, n + 1);
dp[0] = 1;
int[] sum = new int[1 << n];
IntStream.range(0, 1 << n).forEach(i -> {
IntStream.range(0, n).filter(j -> (i & (1 << j)) == 0).forEach(j -> {
int next = i | (1 << j);
if (sum[i] + tasks[j] <= sessionTime) {
sum[next] = sum[i] + tasks[j];
dp[next] = Math.min(dp[next], dp[i]);
} else {
sum[next] = tasks[j];
dp[next] = Math.min(dp[next], dp[i] + 1);
}
});
});
return dp[(1 << n) - 1];
}
}
解释
方法:
题解采用深度优先搜索(DFS)加剪枝的策略来找到最小的工作时间段数。首先,将任务按照所需时间的降序排序,以尝试优先处理耗时较长的任务。算法使用了一个数组 used 来跟踪每个时间段已用的总时间。通过递归地尝试将每个任务放入现有的或新的时间段,并检查这是否能够减少总的时间段数。剪枝发生在当前时间段数已经大于或等于已知的最小时间段数时,此时终止当前路径的搜索。该解决方案的关键是尝试所有可能的组合,并通过剪枝来优化搜索。
时间复杂度:
O((cur + 1)^n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在DFS中,先尝试将任务放入已有的session而不是直接开启新的session?
▷🦆
为什么题解选择了DFS加剪枝而不是动态规划或贪心算法?
▷🦆
在实现剪枝操作时,具体是如何判断当前路径不再值得探索的?
▷