【BZOJ1029】建筑抢修(JSOI2007)-贪心+堆
测试地址:建筑抢修
做法:本题需要用到贪心+堆。
首先,不难想到(实际上可能因为我太菜了我觉得很难)先修截止时间小的。但是直接这样贪心可以找到反例,我们需要找到更好的做法。
考虑一个建筑,如果当前可以修,那就直接修,如果不行,如果这个建筑修理时间比我们目前选择的方案中最长的修理时间要短,就把这个建筑和修理时间最长的建筑互换,这样能使得方案不差的同时,目前的总时间最短。因此我们用一个堆来维护目前方案中修理时间的长短即可。
以下是本人代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
struct task
{
ll t1,t2;
}q[150010];
priority_queue<ll> Q;
bool cmp(task a,task b)
{
return a.t2<b.t2;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&q[i].t1,&q[i].t2);
sort(q+1,q+n+1,cmp);
ll tot=0;
int cnt=0;
for(int i=1;i<=n;i++)
{
if (tot+q[i].t1<=q[i].t2)
{
Q.push(q[i].t1);
tot+=q[i].t1;
cnt++;
}
else if (!Q.empty()&&Q.top()>q[i].t1)
{
tot=tot-Q.top()+q[i].t1;
Q.pop();
Q.push(q[i].t1);
}
}
printf("%d",cnt);
return 0;
}