[bzoj] 2151: 种树 发表于 Mar 22 2015 | 分类于 bzoj | 题意 n个点在一个环,选出k个点,使得点权和最大.点与点不能相邻. 传送门 分析这道题基本上同”[bzoj] 1150: [CTSC2007]数据备份Backup” 代码1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374#include <cstdio>#define Rep(i,l,r) for(i=(l);i<=(r);i++)#define Rev(i,r,l) for(i=(r);i>=(l);i--)int CH , NEG ;template <typename TP>inline void read(TP& ret) { ret = NEG = 0 ; while (CH=getchar() , CH<'!') ; if (CH == '-') NEG = true , CH = getchar() ; while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ; if (NEG) ret = -ret ;}template <typename TP>inline void reads(TP& ret) {truewhile (ret=getchar() , ret<'!') ;truewhile (CH=getchar() , CH>'!') ;}#include <queue>#define maxn 200010LLint a[maxn] ;struct NODE {trueint id ;truebool operator < (const NODE& b) const { return a[id] < a[b.id] ; }} ;int n , k ;std::priority_queue<NODE>h ;int pre[maxn] , back[maxn] ;/*链表*/bool del[maxn] = {0} ;int main() {int i , ans , pos , front , rear ;// #define READtrue#ifdef READtruetruefreopen(".in" ,"r",stdin ) ;truetruefreopen(".out","w",stdout) ;true#endiftrueread(n) , read(k) ;trueif (k>(n/2)) { puts("Error!") ; goto END ; }trueRep (i,1,n)truetrueread(a[i]) ,truetruepre[i] = i-1 , back[i] = i+1 ;truepre[1] = n ; back[n] = 1 ;trueRep (i,1,n)truetrueh.push((NODE){i}) ;trueans = 0 ;truewhile (k --> 0) {truetruewhile (del[h.top().id]) h.pop() ;truetruepos = h.top().id , h.pop() ;truetrueans += a[pos] ;truetruefront = pre[pos] ;truetruerear = back[pos] ;truetruedel[front] = true ;truetruedel[rear] = true ;truetruepre[pos] = pre[front] ;truetrueback[pos] = back[rear] ;truetrueback[pre[pos]] = pos ;truetruepre[back[pos]] = pos ;truetruea[pos] = a[front]+a[rear]-a[pos] ;truetrueh.push((NODE){pos}) ;true}trueprintf("%d\n", ans) ;trueEND : ;true#ifdef READtruetruefclose(stdin) ; fclose(stdout) ;true#elsetruetruegetchar() ; getchar() ;true#endiftruereturn 0 ;}