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; } `
相关文章推荐
- 种树(codevs 1768)
- 种树 (codevs 1653) 题解
- Codevs1653 种树2
- Codevs P1653 种树 2
- 信与信封问题(codevs 1222)
- cURL安装--Cocos Creator项目使用 VS Code 激活脚本编译
- CODE[VS] 1652 淘汰赛制 签到暴力
- (九)ReactNative IDE VSCode插件
- 使vscode调试nodejs代码
- CodeVS4730 特殊等式-1@2@3@...@(N-1)=N
- 【转】【数论】【codevs】1012 最大公约数和最小公倍数问题
- [Codevs] 1173 最优贸易
- codevs 1173 最优贸易(DP+SPFA运用)
- codevs3304水果姐逛街(线段数)
- VScode配合g++编译和调试
- 引水入城(codevs 1066)
- codevs 2597 团伙(并查集)
- Codevs 2833 奇怪的梦境
- 基因变异(codevs 3194)
- 【数论】矩阵乘法&&CODE[VS] 1287