zoukankan      html  css  js  c++  java
  • P1484 种树

    P1484 种树

    题意:

    在n个数中选出至多k个数,且两两不相邻,并使所选数的和最大。 n<=500000

     思路

    • 先建一个堆,把所有点扔进去,当取出队首元素时累加到答案时,把它和它左右两个点一起看成一个点,权值为a[l]+a[r]-a[x],然后把这个点入队
    • 注意维护左右相邻的点

    代码

    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <queue>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    typedef long long LL;
    #define res register int
    
    inline LL read()
    {
    	LL x=0,f=1;char ch;
    	while(!isdigit(ch=getchar())) if(ch=='-') f=-1;
    	while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
    	return f*x;
    }
    const int N=500000+10;
    
    struct node{
    	LL val,id;
    	bool operator<(const node &n2) const {
    		return val<n2.val;
    	}
    };
    int l[N],r[N],a[N];
    bool inv[N];
    int n,k;
    priority_queue<node> q;
    node t;
    
    int main()
    {
    	n=read(); k=read();
    	for(res i=1 ; i<=n ; ++i) {
    		a[i]=t.val=read(); t.id=i;
    		l[i]=i-1; r[i]=i+1;
    		q.push(t);
    	}
    	LL ans=0;
    	while(k--)
    	{
    		while(inv[q.top().id]) q.pop();
    		t=q.top(); q.pop();
    		int num=t.id;
    		if(t.val<0) break;
    		ans+=t.val;
    		t.val = a[num] = a[l[num]]+a[r[num]]-a[num];
    		inv[l[num]]=inv[r[num]]=1;
    		l[num]=l[l[num]]; r[num]=r[r[num]];
    		r[l[num]]=num; l[r[num]]=num;
    		q.push(t);
    	}
    	
    	cout<<ans<<endl;
    	return 0;
    }
    

      

  • 相关阅读:
    NIO简述
    函数式编程
    ReadWriterLock读写锁
    Semaphore工具类使用
    CyclicBarrier工具类使用
    CountDownLatch工具类使用
    创建VUE+Element-UI项目
    <slot>插板使用
    Spring面试题
    实现定时任务的几种方式
  • 原文地址:https://www.cnblogs.com/wmq12138/p/10511971.html
Copyright © 2011-2022 走看看