zoukankan      html  css  js  c++  java
  • [BZOJ]1029: [JSOI2007]建筑抢修

    https://www.lydsy.com/JudgeOnline/problem.php?id=1029

    题意:给出n个建筑的自爆时间和修复时间,求最多在自爆时间前能修复多少建筑。

    一开始的naive想法:这不按自爆时间排个序,第二关键字为修复时间,升序就行?

    但是这样是可以举出反例的,比如存在一个建筑,自爆时间略大于前一个,但是修复时间短,而前一个修复时间长,这两个只能选一个修,显然应该选后面那个修复时间短的,虽然不会增加答案,但是会减少时间

    所以在对y升序排序的基础上,用一个大根堆维护之前出现的最大修复时间,在无法修复时,考虑把前面最大的替换掉(仅在当前建筑修复时间<最大修复时间时)。

    贪心的后悔策略

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<queue>
    
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=150005;
    
    int n;
    struct Node{
        int x,y;
    }a[MAXN];
    bool cmp(const Node &l,const Node &r){
        return l.y==r.y?l.x<r.x:l.y<r.y;
    }
    
    priority_queue<unsigned long long> Q;
    
    int main(){
        n=rd();
        for(int i=1;i<=n;i++){
            a[i].x=rd();a[i].y=rd();
        }
        sort(a+1,a+1+n,cmp);
        long long cur=0;
        unsigned long long cnt=0;
        for(int i=1;i<=n;i++){
            if(cur+a[i].x>a[i].y) {
                if(a[i].x<Q.top()){
                    cur+=(a[i].x-Q.top());
                    Q.pop();Q.push(a[i].x);
                }
                continue;
            }
            cnt++;
            cur+=a[i].x;
            Q.push(a[i].x);
        }
        cout<<cnt<<endl;
        return 0;
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9364400.html

  • 相关阅读:
    微信小程序自定义navigationBar
    微信小程序-自动定位并将经纬度解析为具体地址
    a conexant audio couldnot befound
    平衡二叉树(AVL)java实现
    二叉树的各种非递归遍历
    选择排序
    快速排序
    冒泡排序
    数组洗牌
    haffman树c实现
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9364400.html
Copyright © 2011-2022 走看看