原題網址:此處為連結
個人難度評價: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;
}
};