• 【刷题】BZOJ 2151 种树


    Description

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

    Input

    输入的第一行包含两个正整数n、m。第二行n个整数Ai。

    Output

    输出一个整数,表示最佳植树方案可以得到的美观度。如果无解输出“Error!”,不包含引号。

    Sample Input

    【样例输入1】
    7 3
    1 2 3 4 5 6 7
    【样例输入2】
    7 4
    1 2 3 4 5 6 7

    Sample Output

    【样例输出1】
    15

    【样例输出2】
    Error!
    【数据规模】
    对于全部数据:m<=n;
    -1000<=Ai<=1000
    N的大小对于不同数据有所不同:
    数据编号 N的大小 数据编号 N的大小
    1 30 11 200
    2 35 12 2007
    3 40 13 2008
    4 45 14 2009
    5 50 15 2010
    6 55 16 2011
    7 60 17 2012
    8 65 18 199999
    9 200 19 199999
    10 200 20 200000

    Solution

    贪心题
    把整个环用双向链表串起来
    每次贪心选择价值最大的位置 (x)
    (V[nxt[x]]+V[pre[x]]-V[x]) 替代,它删去 (pre[x])(nxt[x])

    #include<bits/stdc++.h>
    #define ui unsigned int
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    const int MAXN=200000+10;
    int n,m,ans;
    struct node{
    	int id,val,pre,nxt;
    	inline bool operator < (const node &A) const {
    		return val>A.val||(val==A.val&&id<A.id);
    	};
    };
    node tree[MAXN];
    std::set<node> S;
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char ch='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(ch!='')putchar(ch);
    }
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    int main()
    {
    	read(n);read(m);
    	if(n<(m<<1))
    	{
    		puts("Error!");
    		return 0;
    	}
    	for(register int i=1,x;i<=n;++i)read(x),S.insert(tree[i]=(node){i,x,i==1?n:i-1,i==n?1:i+1});
    	while(m--)
    	{
    		node now=*S.begin(),l=tree[now.pre],r=tree[now.nxt],pl=tree[l.pre],pr=tree[r.nxt];
    		S.erase(now);S.erase(l);S.erase(r);S.erase(pl);S.erase(pr);
    		ans+=now.val;
    		now.val=l.val+r.val-now.val;
    		now.pre=pl.id,now.nxt=pr.id;
    		pl.nxt=now.id,pr.pre=now.id;
    		tree[now.id]=now;tree[pl.id]=pl;tree[pr.id]=pr;
    		S.insert(now);S.insert(pl);S.insert(pr);
    	}
    	write(ans,'
    ');
    	return 0;
    }
    
  • 相关阅读:
    进制
    变量
    cmd命令和快捷键
    面向对象和面向过程
    iterations 快捷键
    SQL语句分类和语法
    MySQL语法规范
    Web-Scale-IT 到底是啥?
    安全的应用程序开发和应用程序安全防御
    如何像后端一样写前端代码?
  • 原文地址:https://www.cnblogs.com/hongyj/p/9517457.html
Copyright © 2020-2023  润新知