今天的时间好少啊,晚自修还要去听专题报告,都没有时间刷题了,只有打一道水题练练手了。
这题的解题思路是贪心,对每个节点的T2进行排序,然后从小到大修最多的建筑就行了。
但是这个贪心的思路是有问题的:如果T2最小的节点i的T1很大,但是在i的T2范围内有许多节点的T1很小,不就GG了?
所以我们可以用一个堆来维护当前维修的所有建筑的T1,然后枚举下一个节点,若这个节点可以直接维修就修,若不能就判断这个节点的T1值是否比当前的堆顶小,若比堆顶小,就用当前的节点来替换堆顶的节点,也就是为之后的节点空出更多的时间。
因为博主比较懒,所以就打了一个priority_queue,这样比较节省代码。
附上AC代码:
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
struct note{
int t,w;
bool operator < (const note lyf) const {
return t<lyf.t;
}
}a[150010];
priority_queue <int> que;
int n,now,ans;
int main(void){
scanf("%d",&n);
for (int i=1; i<=n; ++i) scanf("%d%d",&a[i].w,&a[i].t);
sort(a+1,a+1+n);
for (int i=1; i<=n; ++i)
if (now+a[i].w<=a[i].t) now+=a[i].w,++ans,que.push(a[i].w);
else if (!que.empty()&&a[i].w<que.top()) now+=a[i].w-que.top(),que.pop(),que.push(a[i].w);
printf("%d",ans);
return 0;
}