美文网首页
完成所有工作的最短时间

完成所有工作的最短时间

作者: 张隐蔽 | 来源:发表于2021-05-08 16:16 被阅读0次

    题目:给一个整数数组jobs,其中jobs[i]是完成第 i 项工作要花费的时间。

    现在需要将这些工作分配给 k 位工人,所有的工作都应该分配完成,且每项工作只能分配给一个人,工人的工作时间是完成分配给他们的工作的的时间总和。现要求设计一套方案,使工人的最大工作时间得以最小化。即尽可能早的完成所有工作,并求出这个时间。

    1、暴力求解,回溯算法经典模版

    private void backTrack("原始参数") {
        
        if ("终止条件") {
          return;
        }
       
        for (int j = "循环开始初始值"; j < "循环条件"; j++) {
          
          // 作出选择
          backTrack("新的参数");
          // 撤销选择
        }
      }
    

    每份工作都有 K 种分配方案,求出每一种情况下的时间并记录下来,得出一个最小值。
    思路:一共n份工作,每份工作都有可能分配给k个人,链式分配工作

     // 尽可能小的最大工作时间
      int res = Integer.MAX_VALUE;
     /**
       * @param jobs     工作的集合
       * @param jobIndex 当前处理的工作下标
       * @param worker   工人当前的工作情况
       * @param max      worker数组的最大值
       */
      private void backTrack(int[] jobs, int jobIndex, int[] worker, int max) {
        // 如果前面已经得出的res 比传进来的max小,那么就可以忽略本次计算
        // 因为当前已经分配的工作中工人的工作最大值max大于之前得出的最优解, 
        // 后续的工作无论怎么分配都不可能是最优解
        if (max >= res)return;
        // 如果已经处理到了最后一项工作 那么这个时候 记录一下当前的 尽可能小的最大工作时间
        // 取已经求出来的res值和max的最小值
        if (jobIndex == jobs.length) {
          res = Math.min(res, max);
          return;
        }
        // 第jobIndex份工作需要消耗的时间
        int job = jobs[jobIndex];
        Set<Integer> set = new HashSet<>();
        // 分配当前工作,尝试分配给不同的工人
        for (int j = 0; j < worker.length; j++) {
          // 优化点1
          // 同一层中如果已经计算过 就可以直接跳过  比如当前worker = [3,7,6,6,8,3,9]这种情况下,第i份工作分给第三个人和第四个人情况重复 直接过滤掉一次
          if (!set.add(worker[j])) {
            continue;
          }
          // 优化点2 
          // 假如工作分配给第j号工人的时候,发现j号工人的总时间超过了之前求出的最优解
          // 这个时候后续的工作无论怎么分配都不最优,继续下一次循环,将此项工作分配给下一个人
          if (worker[j] + job >= res) {
            continue;
          }
          //将当前工作分配给 j 工人,并记录j工人的工作总时间
          worker[j] += job;
          // 继续分配下一个工作,这时候的工作worker数组重的最大值就是worker[j]和之前最大值max取最大值
          backTrack(jobs, jobIndex + 1, worker, Math.max(worker[j], max));
          // 当前工作去掉 进行下一个循环,即把当前的工作分配给下一个工人
          worker[j] -= job;
        }
      }
    
    时间复杂度:k的n次方,n是jobs的长度

    相关文章

      网友评论

          本文标题:完成所有工作的最短时间

          本文链接:https://www.haomeiwen.com/subject/tabudltx.html