bzoj 1029 [JSOI2007]建筑抢修

优先队列+贪心

先以t2排序,依次枚举,若当前时间+t1<=t2,则累计答案,并将这个建筑扔到大根堆中去

否则,在之前选过修理的建筑中选出t1最大的那个元素,与当前元素作比较,若当前的t1较小,则当前方案更优,扔出队首元素,替换成当前建筑

#include <bits/stdc++.h>
#define m_k make_pair
#define ll long long
using namespace std;
ll n,ti,ans;
struct node
{
    ll t1,t2;
}sh[200000];
priority_queue <pair<ll,int> > q;//大根堆
bool cmp(node a,node b)
{
    return (a.t2<b.t2 || (a.t2==b.t2 && a.t1<b.t1));//以t2排序
}
int main()
{
    scanf("%lld",&n);
    for (int i=1;i<=n;i++)
      scanf("%lld%lld",&sh[i].t1,&sh[i].t2);
    sort(sh+1,sh+1+n,cmp);
    for (int i=1;i<=n;i++)
    {
        if (ti+sh[i].t1<=sh[i].t2)
        {
            ans++;
            ti+=sh[i].t1;
            q.push(m_k(sh[i].t1,i));//选择修理
        }
        else
        {
            int f;
            f=q.top().second;
            if (sh[i].t1>=sh[f].t1)
              continue;
            if (ti+sh[i].t1-sh[f].t1<=sh[i].t2)
            {
                ti+=sh[i].t1-sh[f].t1;
                q.pop();
                q.push(m_k(sh[i].t1,i));//替换
            }
        }
    }
    printf("%lld\n",ans);
}

 

posted @ 2019-03-06 21:35  SevenDawns  阅读(146)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end