zoukankan      html  css  js  c++  java
  • 51Nod 1380 夹克老爷的逢三抽一

    Description

    一开始有一个环,可以选择删除一个元素获得他的权值,同时删除与它相邻的两个元素,其他元素重新形成环,问能获得的最大价值.

    Sol

    堆+贪心.

    一开始从堆中加入所有元素,然后取出一个元素之后,加入他两边的元素之和-该位置的权值,并把左右两点删除.

    一直到取出 (frac {n} {3}) 个元素即可,左右元素可以用链表维护.

    这样取出一个元素了以后可以进行反悔的操作,获得另外两个权值.

    xyx大爷说只要不相邻那么元素个数使得他必然有一种合法的删除方案.

    Code

    #include<cstdio>
    #include<utility>
    #include<queue>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    #define mpr(a,b) make_pair(a,b)
    typedef long long LL;
    const int N = 100005;
    
    int n,b[N],nxt[N],pre[N];
    LL a[N];
    LL ans,tmp;
    priority_queue<pair<LL,int> > q;
    
    inline LL in(LL x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
    	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x; }
    int main(){
    	n=in();
    	for(int i=1;i<=n;i++) a[i]=in(),nxt[i]=i+1,pre[i]=i-1;
    	nxt[n]=1,pre[1]=n;
    	for(int i=1;i<=n;i++) q.push(mpr(a[i],i));
    	
    	for(int i=1,pos,x;i*3<=n;){
    		x=q.top().first,pos=q.top().second,q.pop();
    		if(x<=0) break;
    		if(b[pos]) continue;++i;
    		//cout<<pos<<" "<<x<<endl;
    		ans+=x;
    		tmp=a[nxt[pos]]+a[pre[pos]]-x;
    		a[pos]=tmp;
    		q.push(mpr(tmp,pos));
    		b[nxt[pos]]=1,b[pre[pos]]=1;
    		nxt[pre[pre[pos]]]=pos,pre[nxt[nxt[pos]]]=pos,pre[pos]=pre[pre[pos]],nxt[pos]=nxt[nxt[pos]];
    		//pre[pos]=pre[pre[pos]],nxt[pos]=nxt[nxt[pos]],nxt[pre[pos]]=pos,pre[nxt[pos]]=pos;
    	}cout<<ans<<endl;
    	return 0;
    }
    

      

  • 相关阅读:
    Golang 实现简单的 Web 服务器
    Aliyun linux repo文件
    云服务器查看登录ip和本机出口ip
    10个高效Linux技巧及Vim命令对比
    使用mkfs.ext4格式化大容量磁盘
    LINUX SHELL 多个命令一起执行的几种方法
    GPT分区
    3种方法更改Linux系统的主机名(hostname)
    Nginx代理访问RDS
    Centos7安装Docker
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6026805.html
Copyright © 2011-2022 走看看