Luogu P4053 [JSOI2007]建築搶修

一道貪心題,看數據範圍就知道要套一個數據結構上去。git

別走啊不是什麼很高級的數據結構數據結構

考慮最樸素的想法,按建築的搶修時間排序並先拿小的spa

而後隨便想一想均可以找到一堆反例code

因此咱們就直接考慮模擬這個過程,按報廢時間排序排序

咱們掃描到一個建築時,分狀況討論:it

  • 若是能夠修好,直接拿去修。而且把這個建築扔到一個堆裏(大根堆)。爲後面的操做作準備。
  • 若是不能修好,就將這個建築的修理時間\(t_i\)和堆頂的元素的\(t_j\)比較。若\(t_i<t_j\),咱們就彈出堆頂並選擇修理這個建築(也要扔到堆裏)

貪心的正確性很好證實,咱們在面對一個建築沒法修好時,若能夠放棄以前的一個佔用時間更大的建築而轉修它,確定會減小總耗時io

CODEclass

#include<cstdio>
#include<cctype>
#include<queue>
#include<algorithm>
using namespace std;
const int N=150005;
priority_queue <int> big;
struct data
{
    int t,w;
}a[N];
int n,ans; long long tot;
inline char tc(void)
{
    static char fl[100000],*A=fl,*B=fl;
    return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
    x=0; char ch; while (!isdigit(ch=tc()));
    while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
}
inline bool cmp(data a,data b)
{
    return a.t<b.t;
}
int main()
{
    //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
    register int i; read(n);
    for (i=1;i<=n;++i)
    read(a[i].w),read(a[i].t);
    sort(a+1,a+n+1,cmp);
    for (i=1;i<=n;++i)
    {
        if (tot+a[i].w<=a[i].t) tot+=a[i].w,++ans,big.push(a[i].w); else
        {
            if (a[i].w<big.top()) tot-=big.top(),big.pop(),big.push(a[i].w),tot+=a[i].w;
        }
    }
    return printf("%d",ans),0;
}
相關文章
相關標籤/搜索