leetcode 1723.完成所有工作的最短时间 - 二分+递归
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.完成所有工作的最短时间 - 二分+递归相关推荐
- LeetCode 1723 完成所有工作的最短时间 题解
LeetCode 1723 完成所有工作的最短时间 题解 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工作都应该分配给 ...
- (leetcode)1723. 完成所有工作的最短时间 -2021/5/8
文章目录 1723. 完成所有工作的最短时间 javascript 1723. 完成所有工作的最短时间 javascript 题目: 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i ...
- leetcode 1723. 完成所有工作的最短时间(二分+剪枝+回溯)
给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工作都应该分配给工人,且每项工作只能分配给一位工人.工人的 工作时间 是完 ...
- LeetCode 1723. 完成所有工作的最短时间(DFS+剪枝 / 状态压缩DP)
文章目录 1. 题目 2. 解题 2.1 DFS 2.2 状态压缩DP 265 / 3871, 前6.85% 前3题题解: LeetCode 5649. 解码异或后的数组(位运算) LeetCode ...
- 力扣 1723. 完成所有工作的最短时间 二分+回溯+剪枝/状压dp
https://leetcode-cn.com/problems/find-minimum-time-to-finish-all-jobs/ 思路一:显然最大工作时间满足单调性,所以可以用二分来写.但 ...
- 【LeetCode每日一题】1723. 完成所有工作的最短时间
[LeetCode每日一题]1723. 完成所有工作的最短时间 [1] 1723. 完成所有工作的最短时间 [2] 473. 火柴拼正方形 [1] 1723. 完成所有工作的最短时间 题目: 给你一个 ...
- [leetcode每日一题2021/5/8]1723. 完成所有工作的最短时间
1723. 完成所有工作的最短时间 题目 思路 动态规划 状态转移方程 优化 求和打表 快速枚举每种选取情况jjj的子集ppp 代码 算法复杂度 题目来源于leetcode,解法和思路仅代表个人观点. ...
- LeetCode每日一题: 1723. 完成所有工作的最短时间
1723. 完成所有工作的最短时间 题目 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工作都应该分配给工人,且每项工作 ...
- Leetcode-二分+递归/回溯-1723. 完成所有工作的最短时间
题目1723. 完成所有工作的最短时间: 题解: 递归回溯模板超时 按照模板+简单剪枝,超时 class Solution { private:vector<int> sum;int mi ...
最新文章
- YARN集群维护部分问题汇总
- 影像组学视频学习笔记(24)-文献导读:了解88种降维、分类器组合、Li‘s have a solution and plan.
- Struts2中采用Json返回List对象数据为空解决方案
- 计算机主键盘的布局,计算机键盘的布局,结构和布置
- 7 个致命的 Linux 命令
- Vivado 自定义VHDL的IP核
- html标签转换含义,html标签含义
- 微信小程序引入骨架屏组件
- 在命令行启动vscode
- 中国数控攻牙机市场趋势报告、技术动态创新及市场预测
- test title
- 关于MSDTC - 与基础事务管理器的通信失败 错误解决的小备忘
- Java知识积累——参数个数可变的函数(Varargs)
- mysql的bht_BHT
- 【word论文排版教程4】样式的应用
- PHP 大地坐标系转高德经纬度
- 单片机C语言九个重要的知识点总结
- 机器学习规则学习_使用机器学习发现动作规则
- 用canvas画一个太极八卦图
- 一米OA任意文件读取漏洞
热门文章
- 麒麟子Cocos Creator实用技巧
- 最近抖音火爆特效蚂蚁呀嘿制作教程。
- 华农大学计算机专硕,华南农业大学电子工程学院(人工智能学院)林芳老师课题组招收计算机方向学硕及专硕...
- 论文阅读《Characterizing BDS signal-in-space performance from integrity perspective》1
- css缩2个字,首行缩排2字元怎么设定 css
- 微信小程序客服介绍:如何设置小程序在线客服?
- Python:实现reverse letters反向字母算法(附完整源码)
- 池化层(pooling layer) 感受野(Receptive Field) 神经网络的基本组成
- 关于android某些手机java.lang.UnsatisfiedLinkError: No implementation found for ......的问题
- light7ui 刷新子页面 js不能加载的问题