1. 程式人生 > >BZOJ 1029 建築搶修(貪心堆)

BZOJ 1029 建築搶修(貪心堆)

end p s ring 是否 namespace return nbsp 戰鬥 -1

原題代號:BZOJ 1029

原題描述:

建築搶修

小剛在玩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
先按第二個時間對所有的建築排個序,然後直接貪心是不行的,所以需要用到優先隊列,如果能直接搶修的就搶修,同時將t1的值保存在優先隊列中(因為優先隊列默認大數在頂部)
如果碰到搶修時間不夠的建築,判斷一下優先對列頂部的建築物搶修時間是否大於這個時間不夠的搶修時間,如果大於則進行替換,這樣能留出更多的時間得到最優解
AC代碼:
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <iostream>
# include <fstream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <math.h>
# include <algorithm>
using namespace std;
# define pi acos(-1.0)
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define For(i,n,a) for(int i=n; i>=a; --i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define Fo(i,n,a) for(int i=n; i>a ;--i)
typedef long long LL;
typedef unsigned long long ULL;

struct construction
{
    int t1,t2;
} a[150005];

bool cmp(construction a,construction b)
{
    return a.t2<b.t2;
}

int sum,num;
priority_queue<int>Q;

int main()
{
    int sum=0,num=0;
    int n;
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i].t1>>a[i].t2;
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1; i<=n; i++)
    {
        if(a[i].t1<=a[i].t2-sum)
        {
            Q.push(a[i].t1),sum+=a[i].t1,num++;
        }
        else
        {
            if(num==0)continue;
            if(a[i].t1<Q.top())
            {
                sum-=Q.top()-a[i].t1;
                Q.pop();
                Q.push(a[i].t1);
            }
        }
    }
    cout<<num<<endl;
    return 0;
}

 

BZOJ 1029 建築搶修(貪心堆)