课程表III

发布时间 2023-07-31 15:46:14作者: 失控D大白兔

这里有 n 门不同的在线课程,按从 1 到 n 编号。给你一个数组 courses
其中 courses[i] = [durationi, lastDayi] 表示第 i 门课将会 持续 上 durationi 天课,并且必须在不晚于 lastDayi 的时候完成。
你的学期从第 1 天开始。且不能同时修读两门及两门以上的课程。
返回你最多可以修读的课程数目。

1. 贪心

实际上同样也是动态规划的思维,按截止时间排序,是为了推进时间的方便
当前记录的量表示以当前截止时间为总时间的最大完成课程数目
转移的时候,即时间推进时,如果当前课程可以加入则直接加入,如果不能,若存在更大耗时课程,进行替换,课程数不变,但能留下更多的机动时间
即动态规划记录当前时间内的最大课程量和最大机动时间

class Solution {
public:
    int scheduleCourse(vector<vector<int>>& courses) {
        int n = courses.size();
        sort(courses.begin(), courses.end(), [&](auto& a, auto& b) {
            return a[1] < b[1];});//按截止时间升序排

        priority_queue<int> q;//优先队列
        int total = 0;
        for(auto &course:courses){
            int time = course[0];
            int deadline = course[1];
            if(total+time<=deadline){//可以将当前任务完成
                total += time; //时间推进
                q.push(time);//将消耗时间入队
            }
            else if(!q.empty()&&q.top()>time){//不足以完成当前任务,但存在用时更长的任务
                total -= q.top();
                total += time;//替换掉最长一个任务
                q.pop();
                q.push(time);
            }
        }
        return q.size();
    }
};