MT3032 环形喂猪

简介: MT3032 环形喂猪

93d3f654e08049a78126ee51bdd95a9f.jpg

792379819cc142c68a8ab20d005aa5ae.jpg

思路:

1.输出Error的情况:m>n/2

2.首先将饥饿值放到大根堆中,先喂最饿的猪i,则把i的饥饿值加到sum中;但也又可能喂i-1和i+1,所以此时需要反悔:把i取出来的同时,将a[i-1]+a[i+1]-a[i]放入堆中。(即保留取i,也保留取i-1和i+1的可能性),此时将i-1,i,i+1合并为一个节点

#include <bits/stdc++.h>
using namespace std;
const int N = 4e5 + 10;
int n, m, l[N], r[N], ans, a[N], tot;
bool mark[N];
struct node
{
    int id, v; // v为饥饿值
    bool operator<(const node &a) const
    { // 使用大根堆,重载<号
        return v < a.v;
    }
} tmp;
priority_queue<node> q; // 大根堆
int main()
{
    cin >> n >> m;
    if (m > n / 2)
    {
        cout << "Error!";
        return 0;
    }
 
    else
    {
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        for (int i = 2; i < n; i++)
        { // 处理链表
            l[i] = i - 1, r[i] = i + 1;
            q.push({i, a[i]});
        }
        // 处理环形(使用链表存储)
        l[1] = n, r[1] = 2;
        l[n] = n - 1, r[n] = 1;
        q.push({1, a[1]});
        q.push({n, a[n]});
        tot = n;
        for (int i = 1; i <= m; i++)
        {
            tmp = q.top(); // 取出堆头节点放入tmp中
            q.pop();
            if (mark[tmp.id])
            { // 如果已经被标记,即若取i,则标记i-1和i+1表示不能被取
                i--;
                continue;
            }
            ans += tmp.v; // 没被标记,则加到答案中
            // 新增节点
            a[++tot] = a[l[tmp.id]] + a[r[tmp.id]] - a[tmp.id];
            q.push({tot, a[tot]}); // 合并成一个节点
            // 更新链表中左右指针位置关系
            // 因为取了i就不能取i-1和i+1,所以位置关系类似
            //  i-2 tot i+2    tot为i-1 i i+1  tmp为i
            l[tot] = l[l[tmp.id]]; // tot左边为i-2,即tmp的l的l
            r[l[l[tmp.id]]] = tot; // i-2的右边为tot
            r[tot] = r[r[tmp.id]]; // tot右边为i+2,即tmp的r的r
            l[r[r[tmp.id]]] = tot; // i+2的左边为tot
            // 将这三个节点标记为已被处理
            mark[tmp.id] = mark[l[tmp.id]] = mark[r[tmp.id]] = 1;
        }
        cout << ans;
        return 0;
    }
}


相关文章
|
6月前
|
C++ iOS开发
|
5月前
|
C++ Python
UE C++ 链表
UE C++ 链表
|
算法
BM7 链表中环的入口结点
BM7 链表中环的入口结点
47 0
【LeetCode】BM1 反转链表、NC21 链表内指定区间反转
BM1 反转链表 描述: 给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
48 0