[leetcode 1986][状压DP]完成任务的最少工作时间段

[leetcode 1986][状压DP]完成任务的最少工作时间段
inkOrCloud题目链接
解题思路
首先声明一个数组sum并做预处理,sum[i]表示当前i对应二进制位为1的任务需要消耗的时间和,例如sum[0B1101]表示完成第1、3、4个任务总共需要的时间
1
2
3
4
5
6for i := 1; i < len(tasks); i++ {
m := 1 << i
for j := range m {
sum[m|j] = sum[j] + tasks[i]
}
}0B1011,0B0011,0B1001,0B1010,0B1000,0B0010,0B0001。若当前子集的时间和不超过sessionTime就可以尝试将其作为最后一个时间段,所以dp[i]=min(dp[i^1]+1, dp[dpi^2]+1, ..., dp[i^i]+1),i^j(j为i的非空子集)表示j的补集
1
2
3
4
5
6
7
8
9
10
11
12
13 var n = 1 << len(tasks) //n-1则表示所有任务完成的状态
var dp = make([]int, n)
dp[0] = 0
for i := 1; i < n; i++ {
dp[i] = len(tasks)
//(j-1)&i始终为小于j的最大子集
for j := i; j > 0; j = (j - 1) & i {
if sum[j] <= sessionTime {
dp[i] = min(dp[i^j]+1, dp[i])
}
}
}
return dp[n-1]

![[leetcode 3321][Go][有序集合]计算子数组的 x-sum II](https://s3.inkorcloud.top/image/2025/11/c9f55b2ecb04d16a57547b9f4de294ef.png)
![[leetcode 2589][Go][贪心]完成所有任务的最少时间](https://s3.inkorcloud.top/image/2025/11/b966fd1a91aa1ea098b86e6d778523c2.png)
![[leetcode 3234][Go]统计1显著的字符串的数量](https://s3.inkorcloud.top/image/2025/11/a72a47911de291f51cbb5902e4811c1f.png)
![[leetcode 1611][Go][位运算][记忆化搜索]使整数变为 0 的最少操作次数](https://s3.inkorcloud.top/image/2025/11/9715b5f3d8a7574ded3648767538558e.png)
![[leetcode 2528][Go][二分答案][差分数组][前缀和]最大化城市的最小电量](https://s3.inkorcloud.top/image/2025/11/fa0013722d9361b4383839722394dcf2.png)