文章目录
- 1. 题目
- 2. 解题
1. 题目
你打算利用空闲时间来做兼职工作赚些零花钱。
这里有 n 份兼职工作,每份工作预计从 startTime[i]
开始到 endTime[i]
结束,报酬为 profit[i]
。
给你一份兼职工作表,包含开始时间 startTime,结束时间 endTime 和预计报酬 profit 三个数组,请你计算并返回可以获得的最大报酬。
注意,时间上出现重叠的 2 份工作不能同时进行。
如果你选择的工作在时间 X 结束,那么你可以立刻进行在时间 X 开始的下一份工作。
示例 1:
输入:startTime = [1,2,3,3], endTime = [3,4,5,6], profit = [50,10,40,70]
输出:120
解释:
我们选出第 1 份和第 4 份工作,
时间范围是 [1-3]+[3-6],共获得报酬 120 = 50 + 70。
示例 2:
输入:startTime = [1,2,3,4,6], endTime = [3,5,10,6,9], profit = [20,20,100,70,60]
输出:150
解释:
我们选择第 1,4,5 份工作。
共获得报酬 150 = 20 + 70 + 60。
示例 3:
输入:startTime = [1,1,1], endTime = [2,3,4], profit = [5,6,4]
输出:6提示:
1 <= startTime.length == endTime.length == profit.length <= 5 * 10^4
1 <= startTime[i] < endTime[i] <= 10^9
1 <= profit[i] <= 10^4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-profit-in-job-scheduling
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. 解题
- 先按照结束时间排序
- dp 是map,key 是结束时间,value 是 到结束时间 key 时的最大的收益
- 每次二分查找 map 找到上一个不冲突的结束时间点,进行状态转移
class Solution {
public:int jobScheduling(vector<int>& startTime, vector<int>& endTime, vector<int>& profit) {int n = startTime.size();vector<int> id(n);iota(id.begin(), id.end(), 0);// 生成序列 0,1,2,。。。sort(id.begin(), id.end(),[&](auto a, auto b){return endTime[a] < endTime[b];//按结束时间排序});map<int,int> dp;dp[0] = 0;//边界dp[endTime[id[0]]] = profit[id[0]];//第一个状态int ans = profit[id[0]];for(int i = 1; i < n; i++){int idx = id[i];//序号auto it = dp.upper_bound(startTime[idx]);//这次任务之前的不冲突任务时间点int dp_prev = (--it)->second;//上一个不冲突结束时间点的最大收益dp[endTime[idx]] = max(ans, max(dp[endTime[idx]], dp_prev+profit[idx]));ans = max(ans, dp[endTime[idx]]);}return ans;}
};
600 ms 51.9 MB C++
我的CSDN博客地址 https://michael.blog.csdn.net/
长按或扫码关注我的公众号(Michael阿明),一起加油、一起学习进步!