zoukankan      html  css  js  c++  java
  • bzoj 2151: 种树 STL版

    Description

    A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树。园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n。并且每个位置都有一个美观度Ai,如果在这里种树就可以得到这Ai的美观度。但由于A城市土壤肥力欠佳,两棵树决不能种在相邻的位置(i号位置和i+1号位置叫相邻位置。值得注意的是1号和n号也算相邻位置!)。最终市政府给园林部门提供了m棵树苗并要求全部种上,请你帮忙设计种树方案使得美观度总和最大。如果无法将m棵树苗全部种上,给出无解信息。

    solution

    正解:贪心
    这题标准调整贪心,如果没有相邻限制的话,我们开一个堆每一次取最大的就行了,但是如果存在限制,我们就加入一个后悔操作,来做调整贪心.
    首先如果我们选择了一个点 (i),那么其相邻的点 (i-1) (i+1),都不能选了,所以我们删除这两个点,因为 (i) 与它们两个是互斥的,所以我们加入后悔操作的时候,是用两者之和减去 (a[i]),即我们每选择一个点,我们就加入一个新元素 (a[i+1]+a[i-1]-a[i]),这样就可以做到满足限制条件下的调整了,另外就是维护位置,可以链表直接 (O(1)) 做,或者set维护一下即可

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #include <set>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    typedef long long ll;
    const int N=200005;
    int n,a[N],m;
    struct node{
       int id,val;
       node(){}
       node(int _id,int _val){id=_id;val=_val;}
       bool operator <(const node &pr)const{return val<pr.val;}
    };
    struct data{
       int id,val;
       data(){}
       data(int _id,int _val){id=_id;val=_val;}
       bool operator <(const data &pr)const{return id<pr.id;}
    };
    priority_queue<node>q;
    set<data>s;
    set<data>::iter pre,nxt;
    void work()
    {
       scanf("%d%d",&n,&m);
       for(int i=1;i<=n;i++){
          scanf("%d",&a[i]);q.push(node(i,a[i]));
          s.insert(data(i,a[i]));
       }
       if(n<m*2){puts("Error!");return ;}
    
       ll ans=0;
       for(int i=1;i<=m;i++){
          node t=q.top();q.pop();
          while(!s.empty() && s.find(data(t.id,t.val))==s.end())
             t=q.top(),q.pop();
    
          ans+=t.val;
          if(i==m)break;
          data now=data(t.id,t.val);
          nxt=s.upper_bound(now);
          pre=s.lower_bound(now);
          if(nxt==s.end())nxt=s.begin();
          if(pre==s.begin())pre=--s.end();
          else --pre;
    
          data to=data(t.id,pre->val+nxt->val-t.val);
          s.erase(s.find(now));
          s.erase(pre);
          s.erase(nxt);
          s.insert(to);
    
          q.push(node(to.id,to.val));
       }
       printf("%lld
    ",ans);
    }
    
    int main()
    {
    	work();
    	return 0;
    }
    
    
  • 相关阅读:
    vue 的模板编译—ast(抽象语法树) 详解与实现
    Vue 组件(component)之 精美的日历
    nvm 装 nodejs 重启终端失效的解决方法
    vue 2 仿IOS 滚轮选择器 从入门到精通 (一)
    np.stack() 与 tf.stack() 的简单理解
    PHP 之 Ci框架下隐藏index.php
    Boosting 简单介绍
    Adaboost算法流程及示例
    Python 之 解码汉字乱码(如果gbk、utf8都试过不行,可以试试这个)
    Linux 之 tar和nc传文件
  • 原文地址:https://www.cnblogs.com/Hxymmm/p/7779035.html
Copyright © 2011-2022 走看看