- 完成所有工作的最短时间
给你一个整数数组 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
题解
很巧妙的搜索,我们想到用二分来找这个阈值作为答案,那么能否符合这个阈值就需要暴力递归搜索,搜索比较直白,可以看代码结构。
AC代码
class Solution {
public:
int works[15];
bool check(vector<int>& jobs,int dp,int answear,int k)
{
if(dp>=jobs.size())return true;//所有的工作都被合理安排完了
for(int i=0;i<k;i++)
{
if(works[i]+jobs[dp]<=answear)
{
works[i]+=jobs[dp];
bool res=check(jobs,dp+1,answear,k);
works[i]-=jobs[dp];
if(res)return true;
}
if(works[i]==0||works[i]+jobs[dp]==answear)//当前的工人没被安排任务,或者达到了极限,但是这种情况下都没法符合要求,不用再考虑了,因为i+1往后的工人工作量肯定是小于等于i的,肯定也会不满足
break;
}
return false;
}
static int cmp(int a,int b)
{
return a>b;
}
int minimumTimeRequired(vector<int>& jobs, int k)
{
sort(jobs.begin(),jobs.end(),cmp);
memset(works,0,sizeof(works));
int l=1e9,r=0;
for(int i=0;i<jobs.size();i++)
{
r+=jobs[i];
l=min(l,jobs[i]);
}
int res=r;
while(l<=r)
{
int mid=(l+r)/2;
if(check(jobs,0,mid,k))
{
res=mid;
r=mid-1;
}
else l=mid+1;
}
return res;
}
};