P1792 贪心 + 优先队列

题意

传送门 P1792 [国家集训队]种树

题解

P1484 种树的环版本。贪若心地取权值最大的位置种树,可能出现取相邻位置种树更优的情况。设位置 i i i 的权值为 P i P_i Pi,那么每次贪心选择后,若 P p r e [ i ] + P n x t [ i ] > P i P_{pre[i]}+P_{nxt[i]}>P_i Ppre[i]+Pnxt[i]>Pi,应该取消位置 i i i 的选择,而选择相邻位置,此时保证总选择位置数量增加 1 1 1。那么每次将 i i i 处权值赋为 P p r e [ i ] + P n x t [ i ] − P i P_{pre[i]}+P_{nxt[i]}-P_i Ppre[i]+Pnxt[i]Pi 后加入优先队列,并删除相邻节点。

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define maxn 200005
struct node
{
    int a, id;
    bool operator<(const node &b) const
    {
        return a < b.a;
    }
};
int N, M, A[maxn];
int pre[maxn], nxt[maxn], del[maxn];
priority_queue<node> q;

int main()
{
    scanf("%d%d", &N, &M);
    for (int i = 1; i <= N; ++i)
    {
        scanf("%d", A + i);
        pre[i] = i - 1, nxt[i] = i + 1;
        q.push(node{A[i], i});
    }
    pre[1] = N, nxt[N] = 1;
    if (M > N / 2)
    {
        puts("Error!");
        return 0;
    }
    int res = 0;
    for (int i = 0; i < M; ++i)
    {
        while (del[q.top().id])
            q.pop();
        node t = q.top();
        q.pop();
        res += t.a;
        A[t.id] = A[pre[t.id]] + A[nxt[t.id]] - A[t.id];
        del[pre[t.id]] = del[nxt[t.id]] = 1;
        pre[t.id] = pre[pre[t.id]], nxt[t.id] = nxt[nxt[t.id]];
        nxt[pre[t.id]] = t.id, pre[nxt[t.id]] = t.id;
        q.push(node{A[t.id], t.id});
    }
    printf("%d\n", res);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值