leetcode 1723.完成所有工作的最短时间 - 二分+递归

题干

给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间。
请你将这些工作分配给 k 位工人。所有工作都应该分配给工人,且每项工作只能分配给一位工人。工人的 工作时间 是完成分配给他们的所有工作花费时间的总和。
请你设计一套最佳的工作分配方案,使工人的 最大工作时间得以最小化 。
返回分配方案中尽可能 最小 的 最大工作时间 。

示例 1:
输入:jobs = [3,2,3], k = 3
输出:3
解释:给每位工人分配一项工作,最大工作时间是 3 。

示例 2:
输入:jobs = [1,2,4,7,8], k = 2
输出:11
解释:按下述方式分配工作:
1 号工人:1、2、8(工作时间 = 1 + 2 + 8 = 11)
2 号工人:4、7(工作时间 = 4 + 7 = 11)
最大工作时间是 11 。

提示:
1 <= k <= jobs.length <= 12
1 <= jobs[i] <= 107

知识点&算法

还就那个暴力递归

只有12的数据量…想都不想,一上来就是一手暴力递归,然后直接超时,甚至超过五个元素的样例都过不了

class Solution {
public:int minSum = 0x3f3f3f3f,k;void recur(vector<int> vis,vector<int>& jobs,int preMaxSum,int currentSum,int cnt,int unpickedCnt){int n = jobs.size(),check = 0;if(unpickedCnt > n) return;for(int i = 0 ; i < n ; ++i) check += vis[i];if(check == n){if(cnt == k) minSum = min(minSum,preMaxSum);return;}for(int i = 0 ; i < n ; ++i){if(vis[i] == 0){//选进当前组并开始选下一个人currentSum += jobs[i];vis[i] = 1;recur(vis,jobs,max(preMaxSum,currentSum),0,cnt+1,unpickedCnt);//选进当前组并继续当前人recur(vis,jobs,preMaxSum,currentSum,cnt,unpickedCnt);//不选当前组并开始下个人vis[i] = 0;if(currentSum != 0) recur(vis,jobs,max(preMaxSum,currentSum),0,cnt+1,unpickedCnt+1);//不选当前组并继续当前人recur(vis,jobs,preMaxSum,currentSum,cnt,unpickedCnt+1);}}return;}int minimumTimeRequired(vector<int>& jobs, int k) {this->k = k;vector<int> vis(jobs.size(),0);recur(vis,jobs,0,0,0,0);return minSum;}
};

二分优化下的递归

二分的核心,因为对于我们要求的最小答案,在样例中一定存在可行的大于最小答案的情形,所以可以利用二分搜索来查找可行的最大工作时间。
为了缩小二分的范围,左界设为单个工作中时间最长的,右界设为所有工作的时间总和。
对于搜索过程中的每个工作时间,我们对其进行检查,如果可行就左移右界,查找更小的答案,如果不可行就右移左界,查找更大的答案。
以递归的方式检查当前最大工作时间是否可行。遍历所有工作,并不断回溯分配给每个工人,直到全部分配完毕。
由于分配工作后不能超出当前检查的最大工作时间,超出即不能分配。

题解

二分优化+剪枝递归

剪枝中占比最大的还就是那句workloads[i] == 0

class Solution {public:bool recur(vector<int>& jobs,vector<int>& workloads,int maxWorkload,int idxOfJob){if(idxOfJob >= jobs.size() ) return true;int n = workloads.size(),job = jobs[idxOfJob];for(int i = 0 ; i < n ; ++i){if(workloads[i] + job <= maxWorkload){//可分配的情况workloads[i] += job;//不断递归分配能够满足条件的状况if(recur(jobs,workloads,maxWorkload,idxOfJob+1) ) return true;//不满足条件,回溯workloads[i] -= job;}//不满足上述条件,即不可分配,或当前可分配但此后无法分配//workloads[i] == 0当前工作被分配到一个工人后后续无法分配,由于初状态是0,意味着这个工作不论分配到哪个工人,后续都无法产生可分配的策略;workloads[i] + jobs[...] == maxWorkload的情况为当前可分配但后续出现了不可再分的情况if(workloads[i] == 0 || workloads[i] + job == maxWorkload) break;}return false;}bool check(int workers,vector<int>& jobs,int maxWorkload){vector<int> workloads(workers,0);return recur(jobs,workloads,maxWorkload,0);}int minimumTimeRequired(vector<int>& jobs, int k) {sort(jobs.begin(),jobs.end(),[](int a,int b){return a > b;});int n = jobs.size(),sum = 0;for(int i = 0 ; i < n ; ++i) sum += jobs[i];int l = jobs[0],r = sum;//二分法寻找一个可能的最大工作时间//如果一个最大工作时间存在,则大于他的工作时间一定存在,所以往更小处找//m在可行时,为了往更小处找,r = m ,不可行时往更大处找l = m + 1(m已经不可行)while(l < r){int m = (l + r) >> 1;if(check(k,jobs,m)){//cout<<l<<' '<<r<<' '<<m<<endl;r = m;}else{l = m + 1;}}return l;}
};

leetcode 1723.完成所有工作的最短时间 - 二分+递归相关推荐

  1. LeetCode 1723 完成所有工作的最短时间 题解

    LeetCode 1723 完成所有工作的最短时间 题解 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工作都应该分配给 ...

  2. (leetcode)1723. 完成所有工作的最短时间 -2021/5/8

    文章目录 1723. 完成所有工作的最短时间 javascript 1723. 完成所有工作的最短时间 javascript 题目: 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i ...

  3. leetcode 1723. 完成所有工作的最短时间(二分+剪枝+回溯)

    给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工作都应该分配给工人,且每项工作只能分配给一位工人.工人的 工作时间 是完 ...

  4. LeetCode 1723. 完成所有工作的最短时间(DFS+剪枝 / 状态压缩DP)

    文章目录 1. 题目 2. 解题 2.1 DFS 2.2 状态压缩DP 265 / 3871, 前6.85% 前3题题解: LeetCode 5649. 解码异或后的数组(位运算) LeetCode ...

  5. 力扣 1723. 完成所有工作的最短时间 二分+回溯+剪枝/状压dp

    https://leetcode-cn.com/problems/find-minimum-time-to-finish-all-jobs/ 思路一:显然最大工作时间满足单调性,所以可以用二分来写.但 ...

  6. 【LeetCode每日一题】1723. 完成所有工作的最短时间

    [LeetCode每日一题]1723. 完成所有工作的最短时间 [1] 1723. 完成所有工作的最短时间 [2] 473. 火柴拼正方形 [1] 1723. 完成所有工作的最短时间 题目: 给你一个 ...

  7. [leetcode每日一题2021/5/8]1723. 完成所有工作的最短时间

    1723. 完成所有工作的最短时间 题目 思路 动态规划 状态转移方程 优化 求和打表 快速枚举每种选取情况jjj的子集ppp 代码 算法复杂度 题目来源于leetcode,解法和思路仅代表个人观点. ...

  8. LeetCode每日一题: 1723. 完成所有工作的最短时间

    1723. 完成所有工作的最短时间 题目 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工作都应该分配给工人,且每项工作 ...

  9. Leetcode-二分+递归/回溯-1723. 完成所有工作的最短时间

    题目1723. 完成所有工作的最短时间: 题解: 递归回溯模板超时 按照模板+简单剪枝,超时 class Solution { private:vector<int> sum;int mi ...

最新文章

  1. C++STL容器vector
  2. ASP.NET MVC Bundles 之学习笔记
  3. python读取文件按行分割字符串_python中分割字符串split切割并选择输出 逐行读取文件后字符串拼接...
  4. 并发译文翻译计划(二)
  5. iOS OC语言: Block底层实现原理
  6. 橡胶柱压缩_你玩俄罗斯轮盘吗?剪切安全气囊压缩气瓶的隐患及注意事项
  7. Python 面向对象编程(一)
  8. 全解小程序猜数字游戏 04《 程序员变现指南之 微信QQ 小程序 真的零基础开发宝典》
  9. aardio - 【库】FlexCell表格组件
  10. [xctf] 江苏工匠杯easyphp
  11. 初中计算机竞赛面试题目及答案,2019上半年初中信息技术教师资格面试真题及答案(第一批)...
  12. 关于KNX/IP 网关协议报文解析以及几个注意事项
  13. pta 7-1 走楼梯升级版(递归)
  14. 数据分析:OLS回归分析
  15. 水墨风格化matlab,调色进阶篇:如何调出浓水墨风格?
  16. 邓亚萍的即刻搜索:推民生产品搜索曝光不良食品
  17. 如何利用Python实现工作中的自动化
  18. matlab simulink Buck三电平dcdc变换器
  19. dokuwiki登录设置
  20. Bootstrap(五) 导航条、分页导航

热门文章

  1. Markdown任务列表(实现列表勾选/非勾选操作)
  2. L1-005 考试座位号 (15 分)
  3. 常用数据库的种类与特点
  4. 单个网页的搜索引擎优化(SEO)策略
  5. 将OpenGL渲染的结果保存为图片
  6. Mac 下 unrar 命令
  7. 微信封号被限制的几种原因及解决方法
  8. C语言程序设计笔记(浙大翁恺版) 第七章:函数
  9. Mac升级系统后,idea中Git无法使用:xcrun: error: invalid active developer path
  10. 【Arduino 连接 SD 卡模块实现数据读写】