动态规划-规划兼职工作
动态规划-规划兼职工作
一、问题描述
你打算利用空闲时间来做兼职工作赚些零花钱。这里有 n 份兼职工作,每份工作预计从 startTime 开始到 endTime 结束,报酬为 profit。给你一份兼职工作表,包含开始时间 startTime,结束时间 endTime 和预计报酬 profit 三个数组,请你计算并返回可以获得的最大报酬。
注意:
时间上出现重叠的 2 份工作不能同时进行。
如果你选择的工作在时间 X 结束,那么你可以立刻进行在时间 X 开始的下一份工作。
二、问题分析
例如现在输入一组数据:
startTime = [1,2,3,3]
endTime = [3,4,5,6]
profit = [50,10,40,70]
表示兼职表有4份工作:
工作1:开始时间:1,结束时间:3,薪资:50
工作2:开始时间:2,结束时间:4,薪资:10
工作3:开始时间:3,结束时间:5,薪资:40
工作4:开始时间:3,结束时间:6,薪资:70
第一步:找出最优解的性质,并刻画其结构特征。
简单尝试穷举法:
方案1:工作1或工作2=50或10
方案2:工作1+工作3=50+40=90
方案3:工作1+工作4=50+70=120
…
发现问题:组合很多,由于有起始时间和结束时间导致没有很好的排序组合方案
三、动态规划方程,即递归关系
第二步:递归定义最优值
- dp[i] 表示前i份兼职工作可以获得的最大报酬。
- k 表示满足结束时间小于等于第i−1 份工作开始时间的兼职工作数量。
- profit[i−1]表示第i份工作的薪酬。
- 该公式表示:完成第i份兼职获得的最大报酬=MAX(考虑前一份(i-1)兼职的最大报酬,第i份兼职开始时间前能完成的兼职的最大报酬+第i份兼职的报酬)。
四、代码分析
第三步:自底向上的方式计算最值
1.基本代码和解释
public static int jobScheduling(int[] startTime, int[] endTime, int[] profit, int[] dp, String[] optimal) {// 工作数量int n = startTime.length;// 存储工作的int[][] jobs = new int[n][];// 放入for (int i = 0; i < n; i++) {jobs[i] = new int[]{startTime[i], endTime[i], profit[i]};}// 按结束时间排序Arrays.sort(jobs, Comparator.comparingInt(a -> a[1]));// 对每份工作判断for (int i = 1; i <= n; i++) {// 查找合适的工作// k 表示满足结束时间小于等于第i−1份工作开始时间的兼职工作数量int k = binarySearch(jobs, i - 1, jobs[i - 1][0]);// dp[i]=max(dp[i−1],dp[k]+profit[i−1])// 每份工作薪资和(前一份工作薪资,当前工作开始时间前可以结束的工作薪资+当前工作薪资)dp[i] = Math.max(dp[i - 1], dp[k] + jobs[i - 1][2]);//判断是否选择了i兼职if (dp[i] == dp[i - 1]) {// 如果未选择,表示i-1前是最优解optimal[i] = optimal[i - 1];} else {// 如果选择表示:最优解=i开开始前最优解+ioptimal[i] = (optimal[k] + " " + String.valueOf(i)).trim();}}return dp[n];
}
public static int binarySearch(int[][] jobs, int right, int target) {int left = 0;while (left < right) {int mid = left + (right - left) / 2;if (jobs[mid][1] > target) {right = mid;} else {left = mid + 1;}}return left;}
2.测试
public static void main(String[] args) {// 开始时间int[] startTime = {1, 2, 3, 3};// 结束时间int[] endTime = {3, 4, 5, 6};// 薪资表int[] profit = {50, 10, 40, 70};// 报酬数组int[] dp = new int[startTime.length + 1];// 最优解数组String[] optimal = new String[startTime.length + 1];optimal[0] = " ";int i = jobScheduling(startTime, endTime, profit, dp, optimal);System.out.println("共获得报酬=" + i);System.out.println("工作和薪酬关系=" + Arrays.toString(dp));System.out.println("最优兼职表=" + Arrays.toString(optimal));
}
共获得报酬=120
工作和薪酬关系=[0, 50, 50, 90, 120]
最优兼职表=[ , 1, 1, 1 3, 1 4]
问题总结
在这道动态规划案例中:
要点
完成第i份兼职获得的最大报酬=MAX(考虑前一份(i-1)兼职的最大报酬,第i份兼职开始时间前能完成的兼职的最大报酬+第i份兼职的报酬)。
在计算时考虑当前兼职时,要用到之前子问题的解时,我们直接查兼职与最大薪资表dp就可以简化运算。算法性能分析
- 时间复杂度:O(nlogn),其中 n 是兼职工作的数量。排序需要 O(nlogn),遍历 + 二分查找需要 O(nlogn),因此总时间复杂度为 O(nlogn)。
- **空间复杂度:O(n)。**需要 O(n) 的空间来保存dp。
现实意义
通过学习动态规划,弄懂该案例,不光可以学习如何兼职获取最大收益,也能用在其他和时间有关的规划问题中,
设计动态规划算法的步骤
(1)找出最优解的性质,并刻画其结构特性。
(2)递归地定义最优值。
(3)以自底向上的方式计算最优值
(4)根据计算最优值时得到的信息,构建最优解。
动态规划-规划兼职工作相关推荐
- LeetCode每日一题——1235. 规划兼职工作
LeetCode每日一题系列 题目:1235. 规划兼职工作 难度:困难 文章目录 LeetCode每日一题系列 题目 示例 思路 题解 题目 你打算利用空闲时间来做兼职工作赚些零花钱. 这里有 n ...
- 【LittleXi】规划兼职工作
[LittleXi]规划兼职工作 题目链接 心路历程: 早上起来打开题目,一点思路没有 摆烂点开<戴森球>就到中午了,退出游戏,一眼线段树,直接秒了 总结:打游戏,也可以提高思维能力 解题 ...
- LeetCode 1235. 规划兼职工作(动态规划+二分查找)
文章目录 1. 题目 2. 解题 1. 题目 你打算利用空闲时间来做兼职工作赚些零花钱. 这里有 n 份兼职工作,每份工作预计从 startTime[i] 开始到 endTime[i] 结束,报酬为 ...
- 【1235. 规划兼职工作】
来源:力扣(LeetCode) 链接: 你打算利用空闲时间来做兼职工作赚些零花钱. 这里有 n 份兼职工作,每份工作预计从 startTime[i] 开始到 endTime[i] 结束,报酬为 ...
- 2021-06-03 wms软件如何规划仓库管理工作?
有一些仓库的人员管理.备件管理较为混乱,首先在人员管理方面没有形成一个管理体系,整个仓库人员角色还没有清晰,有时介于售后与仓库之间,工作职责不够明确,导致工作效率不高.其次在人员管理方面没有一个很好的 ...
- 用场景来规划测试工作
姓名:吴发达 性别:男 特点: 新时代的产物:现代典型沙发男:想足不出户就解决无聊 年龄:20 爱好 漫画 在校学生 场景:该沙发男想在周末待在宿舍解决无聊问题,于是待在靠椅上,翘着二郎腿,点击鼠标, ...
- 26岁宝妈去汤臣倍健面试兼职工作
26岁宝妈去汤臣倍健面试兼职工作,居然被嫌弃年龄偏大,太扎心了! 今天下午去汤臣倍健面试仓库文员,HR说需要有会计基础,不然盘点的时候会很吃力,另外加班强度很大,不适合我这样的哺乳期妈妈.看来我有必要 ...
- 分享三个可以在家做的正规兼职工作,看到就是赚到
你可以在家做正式的兼职工作.在线兼职工作值得考虑,时间相对自由.在线兼职收入可能不如线下滴滴和外卖立竿见影,但仍然可以坚持收入.有些人比工作工资发展得更高.当然,天上不会有馅饼,不劳无获. 那么有哪些 ...
- 我爱赚钱吧:学生都可以做的兼职工作
我爱赚钱吧:学生都可以做的兼职工作 数据输入,作为学生打工人气排行榜是排在前面的. 因为很简单,所以谁都能做到,如果没有特别规定,在家里也可以做. 这次,我们就向学生推荐的"数据输入兼职&q ...
最新文章
- 题目11 数值的整数次方
- android 点击图片事件,android图文混排点击事件
- MySQL:从B树到B+树到索引再到存储引擎
- java 二维卡尔曼滤波_卡尔曼滤波(Kalman filtering)算法学习小记
- tar打包排除某个文件夹
- python之路——迭代器和生成器
- word图片嵌入式为何只能看到一部分_Word排版的正确姿势!(Word论文排版教学)...
- mysql使用游标删除数据库_mysql 使用游标进行删除操作的存储过程
- 如何在关闭ssh连接的情况下,让进程继续运行?
- Java 中的异常处理
- [翻译]超炫列表动画的实现
- 推荐几个精致的web UI框架
- Creating and Destroying Objects
- java_函数的内存加载过程
- dubbo service注解用法_dubbo学习(四)配置dubbo 注解方式配置
- Direcshow中视频捕捉和参数设置报告
- Java poi ppt图片置于底层_POI之PPT图片插入简单实例
- 如何制作动态图片gif
- 每个公众号都需要一个社区小程序
- 贝叶斯网络、拉普拉斯平滑