力扣2589 5.16

原题网址:此处为链接

个人难度评价: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;
    }
};
posted @ 2024-05-22 18:59  训练师马文  阅读(9)  评论(0)    收藏  举报