1. 程式人生 > 實用技巧 >CF1271D Portals(反悔貪心)

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