1. 程式人生 > >【BZOJ1029】【JSOI2007】【建築搶修】【貪心+堆】

【BZOJ1029】【JSOI2007】【建築搶修】【貪心+堆】

namespace 一段 new -c iostream man mes mod priority

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最大的。看一下用當前建築取代它會不會更優。

假設是就替換。。求最大值的時候用堆優化一下就好了。。

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
int n,now,ans;
struct use{
    int last,end;
}e[1000001];
priority_queue<int>q;
bool cmp(use a,use b){return a.end<b.end;}
int main()
{
   scanf("%d",&n);
   for (int i=1;i<=n;i++) scanf("%d%d",&e[i].last,&e[i].end);
   sort(e+1,e+n+1,cmp);
   now=0;
   for (int i=1;i<=n;i++)
     if (now+e[i].last<=e[i].end){ans++;q.push(e[i].last);now+=e[i].last;}
     else
      {
        int x;
        if (!q.empty())
        {
         x=q.top();
         if (x>e[i].last&&e[i].last+now<=e[i].end+x)
          {
            q.pop();
            now-=x-e[i].last;
            q.push(e[i].last);
          }
         }
      }
    cout<<ans;
}
?


【BZOJ1029】【JSOI2007】【建築搶修】【貪心+堆】