完成所有工作的最短时间
作者:互联网
难度:困难
给你一个整数数组 jobs
,其中 jobs[i]
是完成第 i
项工作要花费的时间。
请你将这些工作分配给 k
位工人。所有工作都应该分配给工人,且每项工作只能分配给一位工人。工人的 工作时间 是完成分配给他们的所有工作花费时间的总和。请你设计一套最佳的工作分配方案,使工人的 最大工作时间 得以 最小化 。
返回分配方案中尽可能 最小 的 最大工作时间 。
示例 1:
输入:jobs = [3,2,3], k = 3
输出:3
解释:给每位工人分配一项工作,最大工作时间是 3 。
示例 2:
输入:jobs = [1,2,4,7,8], k = 2
输出:11
解释:按下述方式分配工作:
1 号工人:1、2、8(工作时间 = 1 + 2 + 8 = 11)
2 号工人:4、7(工作时间 = 4 + 7 = 11)
最大工作时间是 11 。
提示:
1 <= k <= jobs.length <= 12
1 <= jobs[i] <= 107
解法一:二分 + 状态压缩
class Solution {
public:
int minimumTimeRequired(vector<int>& jobs, int k) {
int n = jobs.size();
vector<int> subsum(1 << n, 0);
for(int i = 1; i < 1 << n; ++i){
for(int j = 0; j < n; ++j)
if(i & (1 << j))
subsum[i] += jobs[j];
}
int left = *max_element(jobs.begin(), jobs.end());
int right = accumulate(jobs.begin(), jobs.end(), 0);
while(left <= right){
int mid = (left + right) / 2;
if(check(jobs, k, subsum, mid))
right = mid - 1;
else
left = mid + 1;
}
return left;
}
bool check(vector<int>& jobs, int k, vector<int>& subsum, int mid){
int n = jobs.size();
vector<long> dp(1 << n, INT_MAX);
dp[0] = 0;
// 从已知算未知的
for(int mask = 0; mask < (1 << n); ++mask){
int rem = ((1 << n) - 1) ^ mask;//剩下没算的
for(int sub = rem; sub; sub = (sub - 1) & rem){
if(subsum[sub] <= mid)
dp[sub ^ mask] = min(dp[sub ^ mask], dp[mask] + 1);
}
}
return dp[(1 << n) - 1] <= k;
}
};
标签:11,jobs,int,所有,工作,vector,完成,短时间,分配 来源: https://www.cnblogs.com/bgyx-hyyy/p/14258441.html