BZOJ1029: [JSOI2007]建築搶修[模擬 貪心 優先佇列]

Candy?發表於2016-09-23

1029: [JSOI2007]建築搶修

Time Limit: 4 Sec  Memory Limit: 162 MB
Submit: 3785  Solved: 1747
[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


 

又被優先佇列模擬虐了

很明顯貪心,在某個建築結束前修復儘量多,並且讓話費時間儘量小

記錄當前時間,按t2排序,如果能修復就修復,並且把t1加進佇列

如果不能修復,取出佇列中最大時間mx,t1<mx的話用修復這個代替修復mx那個會讓總耗時更少,所以替換

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N=150005;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}
int n,t=0,ans=0;
struct data{
    int t1,t2;
    bool operator <(const data &r)const{return t2<r.t2;}
}a[N];
priority_queue<int> q;
int main(){
    n=read();
    for(int i=1;i<=n;i++){a[i].t1=read();a[i].t2=read();}
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++){
        if(t+a[i].t1<=a[i].t2){
            ans++;
            t+=a[i].t1;
            q.push(a[i].t1);
        }else{
            int mx=q.top();
            if(a[i].t1<mx){
                q.pop();
                q.push(a[i].t1);
                t=t-mx+a[i].t1;
            }
        }    
    }
    printf("%d",ans);
}

 

 

 
 

相關文章