题目大意
给定一个
n
个点的环,每个点都有一个权值
求最大权值和。
Data Constraint
题解
题解好机智!支持撤销的贪心!
以
ai
为关键字建立一个大根堆,每个位置维护一个双向链表。
假如当前我们取出了位置
k
上的数,删除
可以这样理解,删去了
k
的前驱和后继保证了不会取到相邻的数。
SRC
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std ;
#define N 200000 + 10
struct Note {
int v , h ;
Note ( int V = 0 , int H = 0 ) { v = V , h = H ; }
} ;
bool operator < ( Note a , Note b ) { return a.v < b.v ; }
priority_queue < Note > Q ;
bool flag[N] ;
int a[N] , Pre[N] , Next[N] ;
int n , m , ans ;
int main() {
scanf( "%d%d" , &n , &m ) ;
for (int i = 1 ; i <= n ; i ++ ) {
scanf( "%d" , &a[i] ) ;
Pre[i] = (i + n) % (n + 1);
Next[i] = (i + 1) % (n + 1) ;
if ( Pre[i] == 0 ) Pre[i] = n ;
if ( Next[i] == 0 ) Next[i] = 1 ;
Q.push( Note( a[i] , i ) ) ;
}
if ( m > n / 2 ) { printf( "Error!\n" ) ; return 0 ;}
while ( !Q.empty() && m ) {
Note top = Q.top() ;
Q.pop() ;
if ( flag[top.h] ) continue ;
m -- ;
ans += top.v ;
top.v = a[top.h] = a[Pre[top.h]] + a[Next[top.h]] - a[top.h] ;
flag[Pre[top.h]] = flag[Next[top.h]] = 1 ;
Pre[top.h] = Pre[Pre[top.h]] ;
Next[top.h] = Next[Next[top.h]] ;
Next[Pre[top.h]] = top.h ;
Pre[Next[top.h]] = top.h ;
Q.push( top ) ;
}
printf( "%d\n" , ans ) ;
return 0 ;
}
以上.