CF1271D Portals(反悔贪心)

这题我们显然可以发现,一个点越被迟处理越优,因此可以先预处理一波,接下来我们发现,如果贪心的在某个点最后可以取的位置去掉,那么可能会出现到后来不够的情况

因此其实我们可以使用反悔贪心的思路,先都取掉,用优先队列维护之前取掉的贡献值,从小到大排序

如果不够了,就把最小的那个去掉,这样兵力就能+1,因此是最优的。

正确性就是因为每个只会贡献一个兵力,所以删掉最小的是最优的。

#include<bits/stdc++.h>
#define getsz(p) (p?p->sz:0)
using namespace std;
typedef long long ll;
typedef pair<ll,int> pll;
const int mod=1e9+7;
const int N=4e5+10;
ll a[N],b[N],c[N];
int s[N];
vector<int> num[N];
int suf[N],d[N];
int main(){
    ios::sync_with_stdio(false);
    int n,m,k;
    cin>>n>>m>>k;
    int i;
    for(i=1;i<=n;i++){
        cin>>a[i]>>b[i]>>c[i];
        d[i]=i;
    }
    while(m--){
        int u,v;
        cin>>u>>v;
        d[v]=max(d[v],u);
    }
    for(i=1;i<=n;i++){
        num[d[i]].push_back(i);
    }
    priority_queue<ll,vector<ll>,greater<ll>> q;
    ll ans=0;
    for(i=1;i<=n;i++){
        while(k<a[i]&&(int)q.size()){
            q.pop();
            k++;
        }
        if(k<a[i]){
            cout<<-1<<endl;
            return 0;
        }
        k+=b[i];
        for(auto x:num[i]){
            k--;
            q.push(c[x]);
        }
    }
    while(k<0&&(int)q.size()){
        k++;
        q.pop();
    }
    if(k<0){
        cout<<-1<<endl;
    }
    else{
        while(q.size()){
            ans+=q.top();
            q.pop();
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

 

posted @ 2020-08-11 11:43  朝暮不思  阅读(164)  评论(0编辑  收藏  举报