建筑维修(贪心)

Posted Hunter丶安

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了建筑维修(贪心)相关的知识,希望对你有一定的参考价值。


入侵者。但是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

我就简单叙述一下题目的解析和用到的方法,首先拿到题目,我就会发现这是一个类似贪心算法的题目;那贪心的是什么呢?
1.我们希望能把花费时间最短的先修好;
2.我们希望保留保持时间最长的在最后;
3.我们要尽快修好即将超时的;

算法:对于这道题,我知道第一个数和第二个数是相关联的,所以希望用到map来进行连接,这是可行的;(循环的使用迭代器即可)。
但我们仔细的想一下,这是一个建筑construction类,包含函数成员和属性(消耗的时间,维持的时间),因此在使用c++时,我们可以用
struct代替类。
至此,我们可以随意的调用两者了;
struct construction
{
    int x,y;
    void Read()
    {
        cin >> x >> y;
    }

    bool operator < (const construction &o) const
    {
        return y < o.y;
    }
}o[maxn];
void solve()
{
    sort(o,o+N);
    int use_time=0,complish=0;
    for(int i=0;i<N;i++)
    {
        if(use_time+o[i].x<=o[i].y)
        {
            use_time+=o[i].x;
            q.push(o[i].x);
            complish ++;
        }
        else
        {
            int  a = q.top();
            if(a>o[i].x && use_time-a+o[i].x<o[i].y)//假设下一个的花费得的时间少于前面一个的时间,同时修好建筑后不超时,说明这个才是局部最优解;
            {
                q.pop();
                q.push(o[i].x);
                use_time += o[i].x-a;
            }

        }
    }
    cout << complish;
}

 借鉴 :JSZX11556

 

以上是关于建筑维修(贪心)的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1029 [JSOI2007]建筑抢修

bzoj 1029

建筑抢修(优先队列的运用)

BZOJ 1029 JSOI2007 建筑抢修 贪心+堆

bzoj 1029: [JSOI2007]建筑抢修 贪心

BZOJ 1029 建筑抢修(贪心堆)