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

    传送门

    1029: [JSOI2007]建筑抢修

    Time Limit: 4 Sec  Memory Limit: 162 MB
    Submit: 4724  Solved: 2121
    [Submit][Status][Discuss]

    Description

      小刚在玩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
    【题目大意】
    有N个被破坏的建筑,修理需要一定时间,并且有时间限制,求最多修理几个建筑。
    【思路】
    贪心+堆
    错误思路1:先修理花费时间少的,留下更多的时间给替他建筑。
    错误思路2:先修理时间限制小的,否则错过时间就不能修理了。
    正确贪心:先将时间限制按升序排序,如果能修就修,不能修就和已经修了的且花费时间最长的比较,如果比已经修过中花费时间
    最长的小,就将这个修过的移除,修这个。
    错误思路1:
    5
    2 21
    2 21
    2  21
    10 10
    10 10
    如果按贪心思路1能修理3个。可是实际能修理4个。
    错误思路2:数据(看的PoPoQQQ dalao的博客):

    5
    10 10
    10 20
    2 21
    2 21
    2 21

    贪心只能修理前两个,而实际上最多可以修理4个

    【code】
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    using namespace std;
    int n,tim,ans;
    struct B
    {
        int spt,lit;
    }build[150002];
    priority_queue<int>q;
    bool cmp(B a,B b)
    {
        return a.lit<b.lit;
     } 
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&build[i].spt,&build[i].lit);
        }
        sort(build+1,build+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            if(tim+build[i].spt<=build[i].lit)
            {
                ans++;
                tim+=build[i].spt;
                q.push(build[i].spt); 
            }
            else
            {
                if(!q.empty())
                {
                    if(q.top()>build[i].spt)
                    {
                        tim-=q.top();
                        tim+=build[i].spt;
                        q.pop();
                        q.push(build[i].spt);
                    }
                }
            }
         } 
         printf("%d
    ",ans);
         return 0;
    }
  • 相关阅读:
    根据汉字获取其的首个字母
    jqure获取单选按钮的值(比如性别)
    dataset 和DataTable的用法
    利用ExcelDataReader封装类 导入表格数据
    批量导入数据.net
    一个按下键盘触发事件的例子
    Build Error 6041: Internal build error
    Word 2010巧妙绘制各种分割线的方法(图文)
    vbscript multiple line syntax
    Update msi using vbscript
  • 原文地址:https://www.cnblogs.com/zzyh/p/6993943.html
Copyright © 2011-2022 走看看