动态规划-规划兼职工作

一、问题描述

你打算利用空闲时间来做兼职工作赚些零花钱。这里有 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)根据计算最优值时得到的信息,构建最优解。

动态规划-规划兼职工作相关推荐

  1. LeetCode每日一题——1235. 规划兼职工作

    LeetCode每日一题系列 题目:1235. 规划兼职工作 难度:困难 文章目录 LeetCode每日一题系列 题目 示例 思路 题解 题目 你打算利用空闲时间来做兼职工作赚些零花钱. 这里有 n ...

  2. 【LittleXi】规划兼职工作

    [LittleXi]规划兼职工作 题目链接 心路历程: 早上起来打开题目,一点思路没有 摆烂点开<戴森球>就到中午了,退出游戏,一眼线段树,直接秒了 总结:打游戏,也可以提高思维能力 解题 ...

  3. LeetCode 1235. 规划兼职工作(动态规划+二分查找)

    文章目录 1. 题目 2. 解题 1. 题目 你打算利用空闲时间来做兼职工作赚些零花钱. 这里有 n 份兼职工作,每份工作预计从 startTime[i] 开始到 endTime[i] 结束,报酬为 ...

  4. 【1235. 规划兼职工作】

    来源:力扣(LeetCode) 链接:   你打算利用空闲时间来做兼职工作赚些零花钱.   这里有 n 份兼职工作,每份工作预计从 startTime[i] 开始到 endTime[i] 结束,报酬为 ...

  5. 2021-06-03 wms软件如何规划仓库管理工作?

    有一些仓库的人员管理.备件管理较为混乱,首先在人员管理方面没有形成一个管理体系,整个仓库人员角色还没有清晰,有时介于售后与仓库之间,工作职责不够明确,导致工作效率不高.其次在人员管理方面没有一个很好的 ...

  6. 用场景来规划测试工作

    姓名:吴发达 性别:男 特点: 新时代的产物:现代典型沙发男:想足不出户就解决无聊 年龄:20 爱好 漫画 在校学生 场景:该沙发男想在周末待在宿舍解决无聊问题,于是待在靠椅上,翘着二郎腿,点击鼠标, ...

  7. 26岁宝妈去汤臣倍健面试兼职工作

    26岁宝妈去汤臣倍健面试兼职工作,居然被嫌弃年龄偏大,太扎心了! 今天下午去汤臣倍健面试仓库文员,HR说需要有会计基础,不然盘点的时候会很吃力,另外加班强度很大,不适合我这样的哺乳期妈妈.看来我有必要 ...

  8. 分享三个可以在家做的正规兼职工作,看到就是赚到

    你可以在家做正式的兼职工作.在线兼职工作值得考虑,时间相对自由.在线兼职收入可能不如线下滴滴和外卖立竿见影,但仍然可以坚持收入.有些人比工作工资发展得更高.当然,天上不会有馅饼,不劳无获. 那么有哪些 ...

  9. 我爱赚钱吧:学生都可以做的兼职工作

    我爱赚钱吧:学生都可以做的兼职工作 数据输入,作为学生打工人气排行榜是排在前面的. 因为很简单,所以谁都能做到,如果没有特别规定,在家里也可以做. 这次,我们就向学生推荐的"数据输入兼职&q ...

最新文章

  1. 题目11 数值的整数次方
  2. android 点击图片事件,android图文混排点击事件
  3. MySQL:从B树到B+树到索引再到存储引擎
  4. java 二维卡尔曼滤波_卡尔曼滤波(Kalman filtering)算法学习小记
  5. tar打包排除某个文件夹
  6. python之路——迭代器和生成器
  7. word图片嵌入式为何只能看到一部分_Word排版的正确姿势!(Word论文排版教学)...
  8. mysql使用游标删除数据库_mysql 使用游标进行删除操作的存储过程
  9. 如何在关闭ssh连接的情况下,让进程继续运行?
  10. Java 中的异常处理
  11. [翻译]超炫列表动画的实现
  12. 推荐几个精致的web UI框架
  13. Creating and Destroying Objects
  14. java_函数的内存加载过程
  15. dubbo service注解用法_dubbo学习(四)配置dubbo 注解方式配置
  16. Direcshow中视频捕捉和参数设置报告
  17. Java poi ppt图片置于底层_POI之PPT图片插入简单实例
  18. 如何制作动态图片gif
  19. 每个公众号都需要一个社区小程序
  20. 贝叶斯网络、拉普拉斯平滑

热门文章

  1. 【MES】MES能为制造企业做什么,解决什么问题?
  2. 圣诞礼物送什么 荣耀畅玩5为你排忧解难
  3. zookeeper客户端 curator的使用
  4. linux 批量convert,使用convert来批量处理图片
  5. Opencv批量处理图片的两种方法
  6. 关于Oracle 级联操作
  7. 基于JavaWeb的学生考勤系统
  8. 用office toll plus 安装office2019 vol版
  9. 【游戏程序设计】Direct 3D 三维地形系统
  10. 诸葛:分析师是如何写好数据研究报告的?