您的位置:首页 > 其它

codevs1342 种树

2016-11-03 20:41 162 查看

题目

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


解题思路

这个题拿到之后想了想dp,发现不行;为什么呢,因为每一个选或者不选,肯定要n^2的算法,那贪心?选最大的不行,因为可能两边值选了加起来比中间的大,所以我们加了最大的值之后可以退回来一个值,表示选两边的值。很明显,这个值就是a[i+1]-a[i]+a[i-1];如果选了这个值,说明选两边的值;可以用优先队列来存储
`#include<queue>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=200010;
int n,m,a
,be
,af
;//af表示这个位置前后面的位置,be表示前面的位置;
bool vis
;
struct node{
int loc,v;
}tmp
;
int tot;
priority_queue<node>q;
bool operator <(node a,node b){
return a.v<b.v;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
if(i==1)be[i]=n;
else be[i]=i-1;
if(i==n)af[i]=1;
else af[i]=i+1;
cin>>a[i];
node tmp;
tmp.loc=i;tmp.v=a[i];
q.push(tmp);
}
if(m>(n/2)){
cout<<"Error!";
return 0;
}
int ans=0;
for(int i=1;i<=m;i++){
node u=q.top();
q.pop();
while(vis[u.loc]){
u=q.top();
q.pop();
}
ans+=u.v;
int bex=be[u.loc],afx=af[u.loc];
vis[bex]=vis[afx]=true;
u.v=a[u.loc]=a[bex]+a[afx]-a[u.loc];
af[u.loc]=af[afx];be[u.loc]=be[bex];
be[af[afx]]=u.loc;af[be[bex]]=u.loc;
q.push(u);
}
cout<<ans<<endl;
}
`
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  贪心