题目

https://www.luogu.org/problemnew/show/P1484

思路

我们可以把选择分为两种, 选择 a[i] 和选择 a[i-1] 、a[i+1] 这样,将坑每3个分成一组,对于每个a[i], 要么就选择a[i],要么就a[i-1],a[i+1]一起选。 然后堆优化贪心。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define ll long long
const int N=500010;
struct node
{
    ll v;
    int id;
    bool operator <(node b) const
    {
        return v < b.v;
    }
};
ll a[N], ans;
int l[N], r[N];
bool bj[N];
priority_queue<node> q;
int main()
{
    int n, k;
    scanf("%d%d", &n, &k);
    for(int i=1; i<=n; i++)
    {
        scanf("%lld", &a[i]);
        q.push((node){a[i], i});
        l[i]=i-1,r[i]=i+1;
    }
    int len=n;
    for(int i=1; i<=k; i++)
    {
        while(!q.empty() && bj[q.top().id]) q.pop();
        if(q.empty() || q.top().v < 0)
            break;
        node t = q.top();q.pop();
        ans += t.v;
        bj[t.id]=bj[l[t.id]]=bj[r[t.id]]=1;
        a[++len]=a[l[t.id]]+a[r[t.id]]-a[t.id];
        int l1=l[t.id],r1=r[t.id];
        l[len]=l[l1],r[len]=r[r1];
        r[l[len]]=len,l[r[len]]=len;
        q.push((node){a[len],len});
    }
    printf("%lld\n", ans);
    return 0;
}