力扣2589 5.16

训练师马文發表於2024-05-22

原題網址:此處為連結

個人難度評價: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;
    }
};