• P1484 种树


    链接:Miku

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

    链表存图,但是要注意创造出来个0和n+1号坑,这会方便我们后续处理的

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

    贪心的部分就是选择最高的,然后把两边的去掉

    等等,我反悔了咋办,我觉得选两边的更好!(这里有一个问题,要不都选,要不都不选,这是可以证明的)

    那么我们就把两边和中间拼成一颗巨树,他的价值是两边之和-中间的(这样再选它,就正好是抵消中间并且变成了两边的和)

    然后优先队列弹弹弹。

    注意:这里有负的,所有要特判。

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

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    using namespace std;
    int n,k;
    int l[500002],r[500002],num[500002];long long v[500002];
    struct tr{
        int l;
        int r;
        int num;
         long long va;
        friend bool operator < (tr a,tr b){
            return a.va<b.va;
        }
    } t[500001],tt;
     long  long ans;
     long long x;
    priority_queue <tr>q;
    int fl[500001];
    int main(){
        scanf("%lld%lld",&n,&k);
        for(int i=1;i<=n;++i){
            scanf("%lld",&x);
            t[i].va=x;
            t[i].l=i-1;f
            t[i].r=i+1;
            t[i].num=i;
            q.push(t[i]);
        }
        t[0].r=1;//省事之极 
        t[n+1].l=n;
        for(int i=1;i<=k;++i){
                while(!q.empty()&&(fl[q.top().num]))//不能选的踢出去 
                q.pop();
                tt=q.top();q.pop();
                if(tt.va<0) {
                break;
                }
                ans+=tt.va;
                x=tt.num;
                t[x].va=t[t[x].l].va+t[t[x].r].va-t[x].va;//额外开一个数组很有必要,不然找不到左右 
                tt.va=t[x].va;
                fl[t[x].l]=fl[t[x].r]=1;//两边踢出去 
                t[x].l=t[t[x].l].l;t[t[x].l].r=x;//把左右合并成巨坑 
                t[x].r=t[t[x].r].r;t[t[x].r].l=x;
                q.push(tt);
        }
        cout<<ans;
        return 0;
    } 
    Ac
  • 相关阅读:
    前端开发资料、实用小工具
    冒泡排序法,二分查找法
    数组练习
    一维数组练习题
    for循环输出菱形
    练习题
    课堂练习
    gO语言的安装和环境变量的配置
    PO BO VO DTO POJO DAO 概念及其作用
    BaseServlet
  • 原文地址:https://www.cnblogs.com/For-Miku/p/13356699.html
Copyright © 2020-2023  润新知