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. YARN集群维护部分问题汇总
  2. 影像组学视频学习笔记(24)-文献导读:了解88种降维、分类器组合、Li‘s have a solution and plan.
  3. Struts2中采用Json返回List对象数据为空解决方案
  4. 计算机主键盘的布局,计算机键盘的布局,结构和布置
  5. 7 个致命的 Linux 命令
  6. Vivado 自定义VHDL的IP核
  7. html标签转换含义,html标签含义
  8. 微信小程序引入骨架屏组件
  9. 在命令行启动vscode
  10. 中国数控攻牙机市场趋势报告、技术动态创新及市场预测
  11. test title
  12. 关于MSDTC - 与基础事务管理器的通信失败 错误解决的小备忘
  13. Java知识积累——参数个数可变的函数(Varargs)
  14. mysql的bht_BHT
  15. 【word论文排版教程4】样式的应用
  16. PHP 大地坐标系转高德经纬度
  17. 单片机C语言九个重要的知识点总结
  18. 机器学习规则学习_使用机器学习发现动作规则
  19. 用canvas画一个太极八卦图
  20. 一米OA任意文件读取漏洞

热门文章

  1. 麒麟子Cocos Creator实用技巧
  2. 最近抖音火爆特效蚂蚁呀嘿制作教程。
  3. 华农大学计算机专硕,华南农业大学电子工程学院(人工智能学院)林芳老师课题组招收计算机方向学硕及专硕...
  4. 论文阅读《Characterizing BDS signal-in-space performance from integrity perspective》1
  5. css缩2个字,首行缩排2字元怎么设定 css
  6. 微信小程序客服介绍:如何设置小程序在线客服?
  7. Python:实现reverse letters反向字母算法(附完整源码)
  8. 池化层(pooling layer) 感受野(Receptive Field) 神经网络的基本组成
  9. 关于android某些手机java.lang.UnsatisfiedLinkError: No implementation found for ......的问题
  10. light7ui 刷新子页面 js不能加载的问题