洛谷 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;
}

 

posted @ 2019-08-31 14:48  神之右大臣  阅读(311)  评论(0编辑  收藏  举报