我们可以用二分枚举这个最小时间,对于合法的时间,总是可以安排k个工人,使得满足要求,这里需要爆搜出是否可以选出k个工人,
bool helper(vector<int>& jobs, vector<int>& workloads, int idx, int limit){
if(idx >= jobs.size()){
return true;
}
for(int i = 0; i < workloads.size(); i++){
if(workloads[i] + jobs[idx] <= limit){
workloads[i] += jobs[idx];
if(helper(jobs, workloads, idx + 1, limit)){
return true;
}
workloads[i] -= jobs[idx];
if(workloads[i] == 0){
break;
}
}
}
return false;
}
以上就是爆搜的过程,需要按时间进行从大到小,排队,进行一个剪枝,否则会超时。
完整代码
class Solution {
public:
int minimumTimeRequired(vector<int>& jobs, int k) {
sort(jobs.begin(), jobs.end(), greater<int>());
int left = jobs[0], right = accumulate(jobs.begin(), jobs.end(), 0);
while(left <= right){
int mid = (left + right) / 2;
if(check(jobs, k, mid)){
right = mid - 1;
}else{
left = mid + 1;
}
}
return left;
}
bool check(vector<int>& jobs, int k, int limit){
// 能否将jobs分成k份,使得每一份时间之和均小于limit
vector<int> workloads(k);
return helper(jobs, workloads, 0, limit);
}
bool helper(vector<int>& jobs, vector<int>& workloads, int idx, int limit){
if(idx >= jobs.size()){
return true;
}
for(int i = 0; i < workloads.size(); i++){
if(workloads[i] + jobs[idx] <= limit){
workloads[i] += jobs[idx];
if(helper(jobs, workloads, idx + 1, limit)){
return true;
}
workloads[i] -= jobs[idx];
if(workloads[i] == 0){
break;
}
}
}
return false;
}
};