贪心思想
(暴力枚举) $O(nlogn + n * max(end_i))$
每个区间按照区间的右端点从小到大排序,这样的话区间i和区间i + 1的交集就是区间i的后缀;
想得到电脑最短的运行时间,对于每个区间的运行时间,我们就需要尽量将运行时间往后放,使得多个区间的运行时间尽可能重叠。
遍历排序后的任务,先统计区间i内的已运行的电脑运行时间点,如果运行时间点个数小于duration,则需要新增时间点。根据贪心原则,尽量把新增的时间点安排在区间的后缀上,这样下一个区间就能统计到更多已运行的时间点。
C++ 代码
class Solution {
public:
int findMinimumTime(vector<vector<int>>& tasks) {
sort(tasks.begin(), tasks.end(), [&](const auto& a, const auto& b) {
if(a[1] == b[1]) return a[0] < b[0];
return a[1] < b[1];
});
// run[t]维护时刻t的任务运行个数
vector<int> run(tasks.back()[1] + 1, 0);
int res = 0;
for(auto& task : tasks) {
int start = task[0], end = task[1], d = task[2];
// 减去与前一个区间重合的运行时长,剩下的运行时长尽可能放在后缀中
d -= reduce(run.begin() + start, run.begin() + end + 1);
// 处理剩下的运行时长,尽量往后放
for(int i = end; d > 0; i--) {
if(!run[i]) {
run[i] = 1;
d--;
res++;
}
}
}
return res;
}
};