bzoj 1029 [JSOI2007]建築搶修 貪心

題意:一個物品兩個值 (1)耗時(2)截止時間

每個物品的獲取要在它的截止時間之前
問最多可以有多少個物品
解:
1、很容易想到要對截止時間進行排序

2、我們從截止時間小的開始 決策,
(1)如果 nowtime+ a[i].t1<=a[i].t2 那麼選擇這個物品

(2)否則,說明now+a[i].t1>a[i].t2.  那麼我們選不選都不會對答案有貢獻,但是如果這個
a[i].t1比較小 那麼我們可以貪心地將前面已經選的物品替換成這個物品  來減小nowtime ---->使得後面更多的物品可以獲取
 

#include<bits/stdc++.h>
using namespace std;
#define en '\n'
#define ll long long
#define pb push_back
ll mo;
const ll maxn =2e5+10;
const ll  inf = 1e8;
template<class T>void rep(T &x){x%=mo;x+=mo;x%=mo;}
template<class T>void rd(T &x)
{
    x=0;ll f=0;char ch=getchar();
    while(ch<'0'||ch>'9')  {f|=(ch=='-');ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    x=f?-x:x;
    return;
}

struct node{
ll t1,t2;
bool operator <(const node &b)const {

    return t2<b.t2;
}
}a[maxn];
priority_queue<ll ,vector<ll>, less<ll> >q;
signed main()
{
#ifdef local
freopen("input2.txt","r",stdin);
#endif // local
    ll n;
    cin>>n;
    for(ll i=1;i<=n;i++){
        rd(a[i].t1),rd(a[i].t2);
    }
    sort(a+1,a+1+n);
    ll now=0,ans=0;
    for(ll i=1;i<=n;i++){
        if(now+a[i].t1<=a[i].t2){
            ans+=1;
            now+=a[i].t1;
            q.push(a[i].t1);
        }else{
            ll mx=q.top();q.pop();now-=mx;
            mx=min(a[i].t1,mx);
            now+=mx;
            q.push(mx);
        }
    }
    cout<<ans<<en;
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章