zoukankan      html  css  js  c++  java
  • 【JZOJ4726】种花 题解(贪心+堆)

    题目大意:在一个长度为$n$的环型序列中取出$m$个数使这$m$个数的和最大,且要求这$m$个数互不相邻。

    ----------------------

    考虑维护$nxt$和$lst$,即一个数的前驱和后继。如果此数被选中,那么$a[now]=a[lst]+a[nxt]-a[now]$并且更新前驱和后继,再将更新过后的数扔入堆中。

    反悔机制。

    操作$m$次后输出$ans$即可。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+10;
    int n,m,a[maxn],nxt[maxn],lst[maxn],ans,mov[maxn];
    struct node{int k;};
    bool operator < (node x,node y) {return a[x.k]<a[y.k];};
    priority_queue<node> q;
    int main()
    {
        scanf("%d%d",&n,&m);
        if (n<m*2)
        {
            printf("Error!");
            return 0; 
        } 
        for (int i=1;i<=n;i++) scanf("%d",&a[i]),q.push((node){i});
        for (int i=1;i<n;i++) nxt[i]=i+1;nxt[n]=1;
        for (int i=2;i<=n;i++) lst[i]=i-1;lst[1]=n;
        while(m--)
        {
            node now=q.top();q.pop();
            while(mov[now.k])
            {
                now=q.top();
                q.pop();
            }
            ans+=a[now.k];
            a[now.k]=a[lst[now.k]]+a[nxt[now.k]]-a[now.k];
            mov[lst[now.k]]=1;
            mov[nxt[now.k]]=1;
            lst[now.k]=lst[lst[now.k]],nxt[lst[now.k]]=now.k;
            nxt[now.k]=nxt[nxt[now.k]],lst[nxt[now.k]]=now.k;
            q.push((node){now.k});
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    10 给予scrapy-redis的分布式爬虫
    pandas 01 序列和数据库昂
    如何控制分布式爬虫结束
    动态导入模块
    docker
    09 scrapy中间件
    scrapy 获取settings中的内容
    session对象的cookies
    文本检测-1-MSER
    CTW1500数据集介绍
  • 原文地址:https://www.cnblogs.com/Invictus-Ocean/p/12814918.html
Copyright © 2011-2022 走看看