bzoj2151: 種樹(貪心+堆)
題目傳送門
。
解法:
今天才學這種經典做法。。
如果選最大的然後刪除兩邊很顯然這種策略是錯誤的。
因為有可能兩邊加起來更優。
那麼上面的做法是無法反悔的。。
給他一個反悔的機會。
那麼就是:
假設選了i,那麼刪除i前後的兩個點。
然後把i這個點的權值變為a[前]+a[後]-a[i]。
這樣再選i的話就表示反悔了選了前後兩個。
維護一下這個位置是否刪除。這個位置的前一個未被刪除的是哪個。後一個未被刪除的是哪個就行了。
具體看程式碼。
程式碼實現:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<iostream>
using namespace std;
struct node {
int w,c;node() {w=c=0;}
friend bool operator <(node n1,node n2){return n1.c<n2.c;}
};priority_queue<node> a;
int q[210000],h[210000],n,m,s[210000];bool v[210000];
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) {scanf("%d",&s[i]);q[i]=i-1;h[i]=i+1;node ss;ss.c=s[i];ss.w=i;a.push(ss);}
if(m*2>n){printf("Error!\n");return 0;}
q[1]=n;h[n]=1;memset(v,false,sizeof(v));int ans=0;
for(int i=1;i<=m;i++) {
while(v[a.top().w]==true)a.pop();
node t=a.top();a.pop();ans+=t.c;int l=q[t.w],r=h[t.w];
node p;p.w=t.w;v[l]=true;p.c+=s[l];v[r]=true;p.c+=s[r];p.c-=t.c;
s[t.w]=p.c;q[t.w]=q[l];h[q[l]]=t.w;h[t.w]=h[r];q[h[r]]=t.w;a.push(p);
}printf("%d\n",ans);
return 0;
}
相關文章
- 【bzoj2151】種樹
- 一種型別的樹貪心型別
- 【ybtoj】【貪心】【堆】【例題1】奶牛曬衣服
- 貪心
- bzoj1150: [CTSC2007]資料備份Backup(堆+貪心)
- 反悔貪心
- Supermarket(貪心)
- CF 1029E Tree with Small Distances 樹形DP or 貪心
- 8.13(優先佇列貪心維護+打表找規律+對頂堆優先佇列+DFS減枝+貪心dp)佇列
- bzoj5177: [Jsoi2013]貪心的導遊(主席樹)JS
- 貪心例題
- 貪心+搜尋
- 樹堆
- P3045 [USACO12FEB] Cow Coupons G (用堆實現反悔貪心)
- HDU 5821 Ball(貪心)
- 貪心模式記錄模式
- 反悔貪心雜題
- 貪心演算法演算法
- 貪心、構造合集
- bzoj3613: [Heoi2014]南園滿地堆輕絮(二分+貪心)
- BZOJ5249: [2018多省省隊聯測]IIIDX(線段樹 貪心)
- D52 樹的直徑+貪心 CF911F Tree DestructionStruct
- CF1039D You Are Given a Tree (樹形 dp + 貪心 + 根號分治)
- 洛谷P3586 [POI2015]LOG(貪心 權值線段樹)
- Luogu P4425 轉盤 題解 [ 黑 ] [ 線段樹 ] [ 貪心 ] [ 遞迴 ]遞迴
- 貪心-刪數問題
- 貪心-*活動選擇
- 24/03/20 貪心(一)
- HDU 6047 Maximum Sequence (貪心)
- HDU 5813 Elegant Construction (貪心)Struct
- 漲薪【貪心】【快速冪】
- Leetcode 貪心:差值調整LeetCode
- Least Cost Bracket Sequence(貪心)ASTRacket
- 刪數問題(貪心)
- 「貪心」做題記錄
- [反悔貪心] Add One 2
- 貪心 做題筆記筆記
- 7.5 - 貪心篇完結