原题网址:此处为链接
个人难度评价:1700
分析:
原本的想法是按开始时间排序后遍历,然后贪心的把下一段的和这一段的放一起,发现不够放了就把不够的算出来截为新的一段。最后发现其实有后效性。
正解的贪心是:按结束时间排序后(当然是升序),贪心的把本段的都放最后。每次放的时候先检查本区间内哪些已经被放了,放了的就减去。
为什么?这样考虑:一个区间剩下的部分和其他的段相交应该都是其后缀。很难理解但手玩之后可以发现这确实不假。
源码:
// 2589*
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
class Solution {
public:
int findMinimumTime(vector<vector<int>>& tasks) {
sort(tasks.begin(), tasks.end(), [](const vector<int> &a, vector<int> &b){return a[1]<b[1];});
int f[2001];
memset(f, 0, sizeof(f));
for (auto i: tasks){
for (int j=i[0]; j<=i[1]; j++){
if (f[j])
i[2] -= 1;
}
int now = i[1];
while (i[2] > 0){
if (f[now] == 0){
f[now] = 1;
i[2] -= 1;
}
now -= 1;
}
}
int ans = 0;
for (int i=1; i<=2000; i++){
if (f[i])
ans += 1;
}
return ans;
}
};
标签:tasks,int,2589,力扣,vector,5.16,now,贪心
From: https://www.cnblogs.com/TrainerMarvin/p/18206916