完成所有工作的最短时间

题目连接

解体思想

利用二分加回溯算法,我们先对数组从大到小排序, 并且把左边界定为jobs[0], 右边界定为jobs数组的和,然后进行二分查找判断, 我们这里的判断是对power数组(存放工人的工作时间)进行进行增加或者减少,如果当前工人可以工作这个时间我们就对它进行增加,进入下一层循环到下一个工作安排。如果这层不可以我们再把安排给这个工人的是时间减少回去。

if(p==0||p+cur==limit) 这句话就是当工人这次安排给他的时间不可以的话,由于我们数组是从大到小排序的所以下一层循环他也是不可以的我们就退出,还有就是如果这次p+cur等于limit的话 我们上面的判断是走不通的,下一层循环也是会走不通所以也退出

解题代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
public:
bool backtrack(vector<int> jobs, vector<int>& power, int idx, int limit){
if(idx>=jobs.size()){
return true;
}
int cur = jobs[idx];
for(auto &p: power){
if(p+cur<=limit){
p+=cur;
if(backtrack(jobs,power,idx+1,limit)) return true;
p-=cur;
}
if(p==0||p+cur==limit) break;
}
return false;

}
bool check(vector<int> jobs,int k,int limit){
vector<int> power(k);
return backtrack(jobs,power,0,limit);
}
int minimumTimeRequired(vector<int>& jobs, int k) {
sort(jobs.begin(),jobs.end(),greater<int>());
int l = jobs[0], r = accumulate(jobs.begin(),jobs.end(),0);
while(l < r){
int mid = (l + r) >> 1;
if(check(jobs,k,mid)){
r = mid;
}else{
l = mid + 1;
}
}
return r;
}
};