题意
- 有
n
节课要被安排,每节课包含两个信息(t, d)
,前者是课程时间(duration),后者是最晚结束时间,问你从1
时刻开始安排,最多可以安排几节课。
思路
- 我们先想贪心,没有找到特别好的贪心策略,但是可以想到一个结论,就是在满足最晚结束时间一样的前提下,
t
小的一定比t
大的安排优先级高,可以很容易的反证一下。 - 那么基于这个思路去想dp,先按照最晚结束时间排序,记录两个信息,
s(i)
表示前i
个课在安排到最多的课程的情况下的最少总用时,dp(i)
是一个向量,记录在上述状态下,所选择的课程用时 - 递推时,若
d(i) < s(i-1) + t(i)
,则判断t(i)
是否小于dp(i - 1)
中最大元素,是则在dp(i)
中替换,并相应更新s(i)
,若d(i) >= s(i-1) + t(i)
,则dp(i)
追加t(i)
,s(i) = t(i) + s(i-1)
dp
可以用优先队列维护,同时可以滚动数组,压掉i
这一维
实现
class Solution {
public:
static bool cmp(const vector<int>& x, const vector<int>& y){
return x[1] < y[1];
}
int scheduleCourse(vector<vector<int>>& courses) {
priority_queue<int> q;
sort(courses.begin(), courses.end(), cmp);
int sum = 0;
for (auto& it : courses){
if (sum + it[0] <= it[1]){
q.push(it[0]);
sum += it[0];
}
else if (q.size() && q.top() > it[0]){
sum += it[0] - q.top();
q.pop();
q.push(it[0]);
}
}
return q.size();
}
};