• luogu1484 种树 (优先队列)


    我每次都想选那个最大的、或者是它旁边的两个一起选,如果这两个一起选会大于那个最大的的话

    那我就先把那个最大的选了,再提供一个反悔的选项(类似于网络流的思路?),就是我可以再把种的树换成它旁边那两个,也是相当于又多种了一个,这个的权值是v[l]+v[r]-v[x]

    所以用一个双向链表维护这个l、r,用一个优先队列维护这个最大值就好了

     1 #include<bits/stdc++.h>
     2 #define pa pair<ll,int>
     3 #define CLR(a,x) memset(a,x,sizeof(a))
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=5e5+10;
     7 
     8 inline ll rd(){
     9     ll x=0;char c=getchar();int neg=1;
    10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    12     return x*neg;
    13 }
    14 
    15 priority_queue<pa> q;
    16 int N,K,nxt[maxn],pre[maxn];
    17 ll v[maxn];
    18 bool flag[maxn];
    19 
    20 int main(){
    21     //freopen("","r",stdin);
    22     int i;
    23     N=rd(),K=rd();
    24     for(i=1;i<=N;i++)
    25         v[i]=rd(),q.push(make_pair(v[i],i));
    26     for(i=1;i<=N;i++)
    27         nxt[i]=i+1,pre[i]=i-1;
    28     nxt[0]=1,pre[N+1]=N;
    29     ll ans=0;
    30     while(K&&!q.empty()){
    31         pa p=q.top();q.pop();
    32         int i=p.second,a=pre[i],b=nxt[i];
    33         if(flag[i]) continue;
    34         if(p.first<=0) break;
    35         ans+=p.first;K--;
    36         flag[a]=flag[b]=1;
    37         v[i]=v[a]+v[b]-p.first;
    38         pre[i]=pre[a],nxt[pre[a]]=i;
    39         nxt[i]=nxt[b],pre[nxt[b]]=i;
    40         q.push(make_pair(v[i],i));
    41     }
    42     printf("%lld
    ",ans);
    43     return 0;
    44 }
  • 相关阅读:
    Access导入MSSQL SERVER
    Centos8停用、启用、查看当前启用的端口
    CentOS下使用VI
    CentOS关机与重启命令
    华为云CentOS8安装FTP
    华为云CentOS8安装JDK
    华为云CentOS8安装Nginx
    华为云CentOS8安装Redis
    华为云CentOS8安装MYSQL
    oracle 本地导入imp bat的写法
  • 原文地址:https://www.cnblogs.com/Ressed/p/9887264.html
Copyright © 2020-2023  润新知