LC.P1723[完成所有工作的最短时间]
方法一:回溯+剪枝(超时)
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
| class Solution { int[] jobs; int n, k; int[] sum; int ans = Integer.MAX_VALUE;
public int minimumTimeRequired(int[] jobs, int k) { this.jobs = jobs; this.k = k; this.n = jobs.length; sum = new int[n]; dfs(0, 0); return ans; }
private void dfs(int cur, int max) { if (max >= ans) return; if (cur == n) { ans = max; return; } for (int i = 0; i < k; ++i) { sum[i] += jobs[cur]; dfs(cur + 1, Math.max(max, sum[i])); sum[i] -= jobs[cur]; } } }
|
- 时间复杂度:$O(k^n)$
- 空间复杂度:$O(k)$
方法二:优化
方法一的分配方式是将每个任务依次分给每个工人,并递归此过程。
为达到最大剪枝效果,可优先将工作分配给空闲的工人
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 37 38 39
| class Solution { int[] jobs; int n, k; int[] sum; int ans = Integer.MAX_VALUE;
public int minimumTimeRequired(int[] jobs, int k) { this.jobs = jobs; this.k = k; this.n = jobs.length; sum = new int[n]; dfs(0, 0, 0); return ans; }
private void dfs(int cur, int used, int max) { if (max >= ans) return; if (cur == n) { ans = max; return; } if (used < k) { sum[used] = jobs[cur]; dfs(cur + 1, used + 1, Math.max(max, sum[used])); sum[used] = 0; } for (int i = 0; i < used; ++i) { sum[i] += jobs[cur]; dfs(cur + 1, used, Math.max(max, sum[i])); sum[i] -= jobs[cur]; } } }
|
- 时间复杂度:$O(k^n)$
- 空间复杂度:$O(k)$