Skip to content

1723. Find Minimum Time to Finish All Jobs 👍

  • Time: $O(k^{|\texttt{jobs}|})$
  • Space: $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
class Solution {
 public:
  int minimumTimeRequired(std::vector<int>& jobs, int k) {
    int ans = accumulate(jobs.begin(), jobs.end(), 0);
    vector<int> times(k);

    ranges::sort(jobs, greater<>());
    dfs(jobs, 0, times, ans);
    return ans;
  }

 private:
  void dfs(const vector<int>& jobs, int s, vector<int>& times, int& ans) {
    if (s == jobs.size()) {
      ans = min(ans, ranges::max(times));
      return;
    }
    for (int i = 0; i < times.size(); ++i) {
      if (times[i] + jobs[s] >= ans)
        continue;
      times[i] += jobs[s];
      dfs(jobs, s + 1, times, ans);
      times[i] -= jobs[s];
      if (times[i] == 0)
        return;
    }
  };
};
 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
class Solution {
  public int minimumTimeRequired(int[] jobs, int k) {
    ans = Arrays.stream(jobs).sum();
    int[] times = new int[k];

    Arrays.sort(jobs);
    Collections.reverse(Arrays.asList(jobs));
    dfs(jobs, 0, times);
    return ans;
  }

  private int ans = 0;

  private void dfs(int[] jobs, int s, int[] times) {
    if (s == jobs.length) {
      ans = Math.min(ans, Arrays.stream(times).max().getAsInt());
      return;
    }
    for (int i = 0; i < times.length; ++i) {
      if (times[i] + jobs[s] >= ans)
        continue;
      times[i] += jobs[s];
      dfs(jobs, s + 1, times);
      times[i] -= jobs[s];
      if (times[i] == 0)
        return;
    }
  }
}
 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
class Solution:
  def minimumTimeRequired(self, jobs: list[int], k: int) -> int:
    ans = sum(jobs)
    times = [0] * k  # times[i] := accumulate time of workers[i]

    # Assign the most time-consuming job first.
    jobs.sort(reverse=True)

    def dfs(s: int) -> None:
      nonlocal ans
      if s == len(jobs):
        ans = min(ans, max(times))
        return
      for i in range(k):
        # There is no need to explore assigning jobs[s] to workers[i] further as
        # it would not yield better results.
        if times[i] + jobs[s] >= ans:
          continue
        times[i] += jobs[s]
        dfs(s + 1)
        times[i] -= jobs[s]
        # It's always non-optimal to have a worker with no jobs.
        if times[i] == 0:
          return

    dfs(0)
    return ans