We have n
jobs, where every job is scheduled to be done from startTime[i]
to endTime[i]
, obtaining a profit of profit[i]
.
You're given the startTime
, endTime
and profit
arrays, you need to output the maximum profit you can take such that there are no 2 jobs in the subset with overlapping time range.
If you choose a job that ends at time X
you will be able to start another job that starts at time X
.
Example 1:
Input: startTime = [1,2,3,3], endTime = [3,4,5,6], profit = [50,10,40,70] Output: 120 Explanation: The subset chosen is the first and fourth job. Time range [1-3]+[3-6] , we get profit of 120 = 50 + 70.
Example 2:
Input: startTime = [1,2,3,4,6], endTime = [3,5,10,6,9], profit = [20,20,100,70,60] Output: 150 Explanation: The subset chosen is the first, fourth and fifth job. Profit obtained 150 = 20 + 70 + 60.
Example 3:
Input: startTime = [1,1,1], endTime = [2,3,4], profit = [5,6,4] Output: 6
Constraints:
1 <= startTime.length == endTime.length == profit.length <= 5 * 10^4
1 <= startTime[i] < endTime[i] <= 10^9
1 <= profit[i] <= 10^4
题目链接:https://leetcode.com/problems/maximum-profit-in-job-scheduling/
题目大意:n个任务,每个任务有开始时间,结束时间和收益,同一时刻只能做一个任务,求最大总收益
题目分析:用结构体存任务信息并按结束时间排序,dp[i]表示到第i个任务时的最大值,容易发现存在三种决策方案
1. 不选第i个,则dp[i] = dp[i - 1]
2. 选第i个,已第i个作为起点(时间点与之前的冲突)
3. 选第i个,并接到第j个后面,j为 max(j) task[j].endTime <= task[i].startTime
第三种情况找的时候可以二分
15ms,时间击败82.16%
class Solution {
class Task {
public int s, e, val;
public Task(int s, int e, int v) {
this.s = s;
this.e = e;
this.val = v;
}
}
public int maxPrePos(int cur, Task[] t) {
int ans = -1, l = 0, r = cur, mid = 0;
while (l <= r) {
mid = (l + r) >> 1;
if (t[mid].e > t[cur].s) {
r = mid - 1;
} else {
ans = mid;
l = mid + 1;
}
}
return ans;
}
public int jobScheduling(int[] startTime, int[] endTime, int[] profit) {
int n = profit.length;
Task[] t = new Task[n + 1];
for (int i = 0; i < n; i++) {
t[i] = new Task(startTime[i], endTime[i], profit[i]);
}
Arrays.sort(t, new Comparator() {
public int compare(Task a, Task b) {
if (a == null) {
return 1;
}
if (b == null) {
return -1;
}
if (a.e > b.e) {
return 1;
} else if (a.e < b.e) {
return -1;
} else {
return a.s > b.s ? 1 : -1;
}
}
});
// for (int i = 0; i < n; i++) {
// System.out.println("s[" + i + "] = " + t[i].s + " e[" + i + "] = " + t[i].e + " v[" + i + "] = " + t[i].val);
// }
int[] dp = new int[n + 1];
dp[0] = t[0].val;
for (int i = 1; i < n; i++) {
dp[i] = Math.max(dp[i - 1], t[i].val);
int pre = maxPrePos(i, t);
//System.out.println("i = " + i + " pre = " + pre);
if (pre != -1) {
dp[i] = Math.max(dp[i], dp[pre] + t[i].val);
}
//System.out.println("dp[" + i + "] = " + dp[i]);
}
return dp[n - 1];
}
}