洛谷 P1484 种树 题解
这是一道标准的带反悔贪心;
利用大根堆来维护最大值:
当选择了num[i]后,反悔了,反之选择选了num[i-1]和num[i+1]时获利便增加了num[i-1]+num[i+1]-num[i]。
所以当num[i]被选时,我们就可以删去num[i-1]和num[i+1],并把num[i]改成num[i-1]+num[i+1]-num[i],放进堆中
#include <bits/stdc++.h> #define int long long using namespace std; int a[1000010]; priority_queue<pair<long long,long long> > q; bool bo[1000010]; int l[1000010],r[1000001]; signed main() { int n,m; cin>>n>>m; for(register int i=1;i<=n;i++){ cin>>a[i]; l[i]=i-1; r[i]=i+1; q.push(make_pair(a[i],i)); } l[n+1]=n; r[0]=1; long long ans=0; for(int i=1;i<=m;i++){ while(bo[q.top().second]){ q.pop(); } int x=q.top().second; long long tmp=q.top().first; q.pop(); if(tmp<0) break; ans+=tmp; a[x]=a[l[x]]+a[r[x]]-a[x]; bo[l[x]]=1; bo[r[x]]=1; l[x]=l[l[x]]; r[x]=r[r[x]]; r[l[x]]=x; l[r[x]]=x; q.push(make_pair(a[x],x)); } cout<<ans; }
众人皆醉我独醒,举世皆浊我独清