The main idea: N number around a circle, select a number can not choose its adjacent two number, asked to choose the number of M, the maximum value is how much.
The maximum number of n is maintained with the heap first, each time the maximum value added to the answer, select a number after it is possible to choose it adjacent two better than him, so the next two number is deleted, the number of the selected value to the left of the number + the number on the right-the number of the election, if the next time the number is not selected to replace this number for another two, Select M to take the m number. A number of the left and right sides of the number of the two-way linked list to do it.
The code is as follows:
varN,m,x,i,ans:longint; L,r,heap,pos,a:Array[0..200001] ofLongint;procedureDown (i:longint);varT,j:longint;begin while(i<<1<=n) Do begin if(i<<1=n)or(a[heap[i<<1]]>a[heap[i<<1 or 1]]) Thenj:=i<<1 Elsej:=i<<1 or 1; ifA[HEAP[I]]<A[HEAP[J]] Then beginT:=heap[i];heap[i]:=heap[j];heap[j]:=T; T:=pos[heap[i]];p Os[heap[i]]:=pos[heap[j]];p os[heap[j]]:=T; I:=J; End Elseexit; End;End;procedureUp (i:longint);varT:longint;begin whileI>1 Do begin ifA[heap[i]]>a[heap[i>>1]] Then beginT:=heap[i];heap[i]:=heap[i>>1];heap[i>>1]:=T; T:=pos[heap[i]];p os[heap[i]]:=pos[heap[i>>1]];p os[heap[i>>1]]:=T; I:=i>>1; End Elseexit; End;End; beginreadln (n,m); if(m>n>>1) ThenWriteln ('error!') Else begin fori:=1 toN Do beginread (a[i]); L[i]:=i-1; r[i]:=i+1; heap[i]:=i;pos[i]:=i;up (i); End; l[1]:=n;r[n]:=1; fori:=1 toM Do beginx:=heap[1];inc (ans,a[x]); A[X]:=a[l[x]]+a[r[x]]-A[x];d own (pos[x]); A[L[X]]:=-maxlongint;down (Pos[l[x]); l[x]:=L[l[x]]; A[R[X]]:=-maxlongint;down (Pos[r[x]); r[x]:=R[r[x]]; L[R[X]]:=x;r[l[x]]:=x; End; Writeln (ANS); End;End.View Code
PS: I know the heap can be taken to delete elements Qaq
bzoj2151: Planting trees (doubly linked list + heap)