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; }
没有人不辛苦,只有人不喊疼