题意:给定一个长度为n的序列a1,a2,...,an,每次可以将ai和a+1合并为max{ai,ai+1},每次合并的代价为max{ai,ai+1},求最少的代价将序列合并成一个元素
贪心思想:一个数总是和它左右两边第一个大于它的数中较小的那个合并
顺序处理,单调栈维护
对于元素ai,
如果它大于等于栈顶元素,说明栈顶元素的左右两边第一个大于它的数已经找到,即ai和stack[top-1],比较二者大小选择小的那个合并即可,重复此操作直到栈顶元素大于ai(找到它左边第一个大于它的数)
如果它小于栈顶元素,那么直接入栈即可
最后把栈中元素一个一个弹出更新答案即可
var
x,top,n :longint;
i :longint;
z :array[0..1000010] of longint;
ans :int64;
function max(a,b:longint):longint;
begin
if a<b then exit(b) else exit(a);
end;
begin
read(n);
read(z[1]); top:=1; z[0]:=maxlongint div 10;
for i:=2 to n do
begin
read(x);
while (top>0) and (x>=z[top]) do
begin
if (x>z[top-1]) then
begin
inc(ans,int64(z[top-1])); dec(top);
end else
begin
inc(ans,int64(x)); dec(top);
end;
end;
inc(top); z[top]:=x;
end;
while (top>1) do
begin
inc(ans,int64(z[top-1]));
dec(top);
end;
writeln(ans);
end.
——by Eirlys