Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务活动详情
一、题目描述
给定n个工人,和m个任务,每个任务有完成所需的时间,工人都是一样的。求一个分配方案,最小化最大的工人耗时,输出这个方案。
数据范围
n <= 12
二、思路分析
首先,我们立即就想到了二分答案,这很容易能看出是正确的。
但更大的问题是——如何进行 check ?
朴素想法: 贪心,依次对每个工人进行分配,从大的任务先开始,不能分了换下一个工人。这似乎很有效,但是实践结果是被最后几个数据卡了,贪心并不是最优解。
那怎么办呢?
不朴素想法: 因为人数很少,所以我们可以考虑使用暴搜,依次尝试把任务分配给每个工人,外加一些细节上的剪枝,比如说当某个工人无法分配任何任务的时候,那它之后的那些工人也就不需要再尝试了。
三、AC代码
class Solution {
public:
int n;
int load[1000];
int a[10000];
bool check(int mid, int k, int now) {
if (now == n) return true;
for (int i=0; i<k; i++) {
if (load[i] + a[now] <= mid) {
load[i] += a[now];
if (check(mid, k, now + 1)) return true;
load[i] -= a[now];
}
if (load[i] == 0) return false;
}
return false;
}
int minimumTimeRequired(vector<int>& jobs, int k) {
n = jobs.size();
for (int i=0; i<n; i++) a[i] = jobs[i];
sort(a + 0, a + 0 + n);
for (int i=0; i<n/2; i++) swap(a[i],a[n-i-1]);
int l=0, r = 120000000;
int ans = 999999999, mid;
while (l <= r) {
for (int i=0; i<20; i++) load[i]=0;
mid = (l + r) / 2;
if (check(mid, k, 0)) {
ans = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
return ans;
}
};
四、总结
一开始考虑不够充分,贪心失败了,以后应当所思考一下贪心的正确性,避免浪费时间。