题目:
- 完成所有工作的最短时间
给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间。 请你将这些工作分配给 k
位工人。所有工作都应该分配给工人,且每项工作只能分配给一位工人。工人的 工作时间
是完成分配给他们的所有工作花费时间的总和。请你设计一套最佳的工作分配方案,使工人的 最大工作时间 得以 最小化 。 返回分配方案中尽可能
最小 的 最大工作时间 。
执行结果
代码:
class Solution {
public static void main(String[] args) {
int a[] = {250,250,256,251,254,254,251,255,250,252,254,255};
int b = 10;
System.out.println(System.currentTimeMillis());
System.out.println((new Solution()).minimumTimeRequired(a,b));
System.out.println(System.currentTimeMillis());
}
public int minimumTimeRequired(int[] jobs, int k) {
if(jobs.length<=k){
return getMaxTime(jobs);
}
// 贪心算法,简单认为 倒序再分配就能达到较优秀的答案
int fastResult = fast(jobs,k);
minResult = fastResult;
dfs(jobs,jobs.length-1,new int[k],0);
return minResult;
}
int minResult;
/**
*
* @param jobs job.index
* @param index
* @param times
* @return
*/
public int dfs(int[] jobs, int index, int times[], int maxTime){
Set<Integer> difWorkers = new HashSet<>(times.length);
for(int p1=0;p1<times.length;p1++ ){
int preMaxTime = maxTime;
// 分配任务到当前人
if(difWorkers.contains(times[p1])){
continue;
}else {
difWorkers.add(times[p1]);
}
times[p1] = times[p1] + jobs[index];
index--;
maxTime = Math.max(times[p1],preMaxTime);
if(times[p1]>=minResult){
// 分配当前任务到下一个人 分支2
index++;
times[p1] = times[p1] - jobs[index];
maxTime = preMaxTime;
}else {
// 结果
if(index<0){
minResult = Math.min(minResult,maxTime);
// 分配当前任务到下一个人 分支2
index++;
times[p1] = times[p1] - jobs[index];
maxTime = preMaxTime;
continue;
}
// 分配下一个任务 分支1
dfs(jobs, index, times, maxTime);
// 分配当前任务到下一个人 分支2
index++;
times[p1] = times[p1] - jobs[index];
maxTime = preMaxTime;
}
}
return Integer.MAX_VALUE;
}
public int fast(int[] jobs, int k) {
Arrays.sort(jobs);
int times[] = new int[k];
for(int i = jobs.length-1;i>=0;i--){
int targetWork = getMinIndex(times);
times[targetWork] = times[targetWork] + jobs[i];
}
return getMaxTime(times);
}
private int getMinIndex(int times[]){
int minIndex = 0;
int minTime = Integer.MAX_VALUE;
for(int i = 0;i<times.length;i++){
if(times[i]==0){
return i;
} else {
if(minTime>times[i]){
minIndex = i;
minTime = times[i];
}
}
}
return minIndex;
}
private int getMaxTime(int times[]){
int maxIndex = 0;
int maxTime = 0;
for(int i = 0;i<times.length;i++){
if(maxTime<times[i]){
maxIndex = i;
maxTime = times[i];
}
}
return maxTime;
}
}
解题思路:
遍历所有工作,每个工作 可能分配给任意人员。遍历所有可能。
优化思路:
1.先贪心算法算出一个较优解,用这个解去过滤分支
2.一个工作分配给不同人,若这些人已有的工作量一样,则可认为 分配给他们 是一个分支、一种情况
备注
此文只作为个人学习记录。不保证代码可读,不保证性能多好。