完成所有任务的最少时间

题目

6318. 完成所有任务的最少时间


你有一台电脑,它可以 同时 运行无数个任务。给你一个二维整数数组 tasks ,其中 tasks[i] = [starti, endi, durationi] 表示第 i 个任务需要在 闭区间 时间段 [starti, endi] 内运行 durationi 个整数时间点(但不需要连续)。

当电脑需要运行任务时,你可以打开电脑,如果空闲时,你可以将电脑关闭。

请你返回完成所有任务的情况下,电脑最少需要运行多少秒。

示例 1:

1
2
3
4
5
6
7
输入:tasks = [[2,3,1],[4,5,1],[1,5,2]]
输出:2
解释:
- 第一个任务在闭区间 [2, 2] 运行。
- 第二个任务在闭区间 [5, 5] 运行。
- 第三个任务在闭区间 [2, 2] 和 [5, 5] 运行。
电脑总共运行 2 个整数时间点。

示例 2:

1
2
3
4
5
6
7
输入:tasks = [[1,3,2],[2,5,3],[5,6,2]]
输出:4
解释:
- 第一个任务在闭区间 [2, 3] 运行
- 第二个任务在闭区间 [2, 3] 和 [5, 5] 运行。
- 第三个任务在闭区间 [5, 6] 运行。
电脑总共运行 4 个整数时间点。

提示:

  • 1 <= tasks.length <= 2000
  • tasks[i].length == 3
  • 1 <= starti, endi <= 2000
  • 1 <= durationi <= endi - starti + 1

题解

方法一:

思路

贪心

首先对区间进行右端点升序排序。

对于一个区间的duration个数应该尽可能的放在区间右端,以便让后面的区间能与当前尽可能多的重叠。

所以当前区间的duration应该减去前面区间在本区间放置的位置个数,然后从区间右端向左寻找空位放置。

实际复杂度$O(n^2)$

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public:
int findMinimumTime(vector<vector<int>>& tasks) {
sort(tasks.begin(), tasks.end(), [&](auto& a, auto& b) {
return a[1] < b[1];
});
vector<int> d(2001);
int n = tasks.size();
for (auto& i:tasks) {
int r = i[2];
for (int j=i[0]; j<=i[1]; j++) {
r -= d[j]==1;
}
if (r>0) {
for (int j=i[1]; j>=i[0]; j--) {
if (d[j]) continue;
d[j] = 1;
if (--r == 0) break;
}
}
}
return accumulate(d.begin(), d.end(), 0);
}
};