• 建筑抢修——贪心反悔堆


    题面

    小刚在玩(JSOI)提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,(T)部落消灭了所有

    (z)部落的入侵者。但是T部落的基地里已经有(N)个建筑设施受到了严重的损伤,如果不尽快修复的话,这

    些建筑设施将会完全毁坏。现在的情况是:(T)部落基地里只有一个修理工人,虽然他能瞬间到达任何一

    个建筑,但是修复每个建筑都需要一定的时间。同时,修理工人修理完一个建筑才能修理下一个建筑,

    不能同时修理多个建筑。如果某个建筑在一段时间之内没有完全修理完毕,这个建筑就报废了。你的任

    务是帮小刚合理的制订一个修理顺序,以抢修尽可能多的建筑。

    输入格式

    第一行是一个整数(N),接下来(N)行每行两个整数(T1,T2)描述一个建筑:修理这个建筑需要(T1)秒,如果在

    (T2)秒之内还没有修理完成,这个建筑就报废了。

    输出格式

    输出一个整数(S),表示最多可以抢修(S)个建筑.

    输入输出样例

    输入

    4
    100 200
    200 1300
    1000 1250
    2000 3200
    

    输出 #1复制

    3
    

    说明/提示

    (N < 150,000; T1 < T2 < maxlongint)

    思路

    先把所有的建筑的 (T2) 按照从小到大的顺序排个序,然后再将建筑逐次的“修复”。 “修复”的过程中,我们

    会遇到这样的状况:修复当前的建筑需要花费的时间加上已经使用了的时间,超过了修复当前建筑的截

    止时间。如果排在这个建筑前面的已经被修复了的建筑中,有某个建筑的修复时间大于当前这个建筑

    的修复时间,那么就不修复那个建筑,反而把当前的建筑修复了(取代)。 这会将当前已经使用的时间

    减少,为后来修复更多的建筑提供了更大的可能。 (可以用Exchange Argument----easily证明)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    priority_queue<int,vector<int> ,less<int> > heap;
    long long n;
    const int N=2001000;
    struct node{
    	long long t1,t2;
    }pot[N];
    long long ans;
    long long sum;
    bool cmp(node a,node b)
    {
    	return a.t2<b.t2;
    }
    
    
    int main()
    {
    	scanf("%lld",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%lld%lld",&pot[i].t1,&pot[i].t2);
    	}
    	sort(pot+1,pot+1+n,cmp);
    	for(int i=1;i<=n;i++)
    	{
    		sum+=pot[i].t1;
    		heap.push(pot[i].t1);
    		if(sum<=pot[i].t2)
    		{
    			ans++;
    		}
    		else{
    			sum-=heap.top();
    			heap.pop();
    		}
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    

    推荐博客

  • 相关阅读:
    机器学习回顾篇(14):主成分分析法(PCA)
    Elasticsearch系列---前缀搜索和模糊搜索
    Elasticsearch系列---近似匹配
    Elasticsearch系列---多字段搜索
    Elasticsearch系列---深入全文搜索
    Elasticsearch系列---shard内部原理
    Elasticsearch系列---结构化搜索
    01、Spring环境搭建
    02、Hibernate开发步骤
    01、Hibernate安装配置
  • 原文地址:https://www.cnblogs.com/bangdexuanyuan/p/13951957.html
Copyright © 2020-2023  润新知