分析:不好理解,大体上知道了优化的方向,但是需要单调队列和平衡树(或堆)来维护。
比较难以理解。
f[i]=min{f[k]+max{a[k+1],.....,a[i]}}.
n2的枚举没有问题,优化势在必行。
我们另A[I,J]表示i到j的最大值,那么如果A[i+1,j]=A[i+2,j],那么f[i]+A[i+1,j]<f[i+1]+A[i+2,j],
所以很显然f[i]=min{f[k]+A[k+1,i]}有用的K值都是满足某段区间的最大值。
如果用单调队列维护a[i]使队列中的元素a值单调递减,那么显然可以用于更新的就是a[q[i]]+f[q[i-1]],但是与其他题目不同的是队首元素并不是最优的,所以可以用堆或者平衡树来迅速找到最大值。
核心代码:
procedure ins(c,d:longint);begin sum:=sum+c; while sum>m do begin inc(last); sum:=sum-a[last]; end; while (v[tail]<=c) and(tail>head) do begin delete(z[tail]); dec(tail); end; inc(tail); v[tail]:=c; p[tail]:=d;end;procedure solve;var i: longint;begin for i:= 1 to n do begin ins(a[i],i); while p[head+1]