• 建筑抢修(堆优先队列和贪心的结合)


    小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的
    入侵者。但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会完全
    毁坏。现在的情况是:T部落基地里只有一个修理工人,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需
    要一定的时间。同时,修理工人修理完一个建筑才能修理下一个建筑,不能同时修理多个建筑。如果某个建筑在一
    段时间之内没有完全修理完毕,这个建筑就报废了。你的任务是帮小刚合理的制订一个修理顺序,以抢修尽可能多
    的建筑。

    Input

      第一行是一个整数N接下来N行每行两个整数T1,T2描述一个建筑:修理这个建筑需要T1秒,如果在T2秒之内还
    没有修理完成,这个建筑就报废了。

    Output

      输出一个整数S,表示最多可以抢修S个建筑.N < 150,000;  T1 < T2 < maxlongint

    Sample Input

    4
    100 200
    200 1300
    1000 1250
    2000 3200

    Sample Output

    3
    个人体会:好不容易简单学会了简单贪心,堆这一关确实卡住了,借鉴了网上的思路。其实认真想还是可以想到的,在贪心的基础上,若遇到不能抢修的就依次将推顶的元素拿出来,继续修理,这样即使后面存在最优解也能一起算上去了。
    就是我们维护一个大根堆,每修理一栋建筑,我们就把这栋建筑的start值加入堆,若当前无法修理,我们判断堆顶是否比这栋建筑的start大。如果大,取消修理堆顶,改为修理当前建筑
    同时给上stl优先数列中一般数据和结构体的代码
    一般数据从大到小是priority_queque<int>pq;反过来就是priority_queue<int,vector<int>,greater<int>>pq;
    对于结构体
     1 Struct Node
     2 {
     3    int priority;
     4   int value;
     5 friend bool operator < (Node t1,Node t2)
     6 {
     7    return t1.priority<t2.priority;
     8 }
     9 };
    10 priority_queue<Node>pq;

    现在给出题目正解

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 struct time
     7 {
     8     int start;
     9     int send;
    10 
    11 }t[150005];
    12 bool cmp(const struct time &a,const struct time& b)
    13 {
    14     return a.send<b.send;
    15 
    16 }
    17 int main()
    18 {
    19     int n;
    20     cin>>n;
    21     priority_queue<int >s;
    22     int ti=0;
    23     int sum=0;
    24    for(int i=0;i<n;i++)
    25     cin>>t[i].start>>t[i].send;
    26     sort(t,t+n,cmp);
    27     for(int i=0;i<n;i++)
    28       {
    29           if(t[i].start+ti<=t[i].send) {ti+=t[i].start;s.push(t[i].start);sum++;}
    30           else  if(t[i].start<s.top())
    31           {
    32               ti=ti-s.top()+t[i].start;
    33               s.pop();
    34               s.push(t[i].start);
    35 
    36 }
    37 }
    38     cout<<sum<<endl;
    39    return 0;
    40 
    41 }


  • 相关阅读:
    疯狂学java的第七天
    疯狂学java的第六天
    疯狂学java的第五天
    学java的第四天
    学java的第三天
    javaSE_20_常用API(包装类丶BigInteger类丶BigDecimal类 )
    javaSE_19_常用API(String类丶StringBuffer类)
    javaSE_17_内部类丶常用的引用类型用法总结
    javaSE_15_package和import丶访问控制权限
    javaSE_14_抽象类丶接口
  • 原文地址:https://www.cnblogs.com/blvt/p/7212440.html
Copyright © 2020-2023  润新知