首先这道题有一个很重要的贪心就是
在保证所有干草堆都能参与搭建的前提下,我们尽量使最底层的宽度小,这样搭起来的的干草堆高度一定是最高的
当我们以第i个干草堆为一层,显然最优的情况是找到一个尽可能小的j (i<=j<=n)
使sum[j-1]-sum[i-1]>=h[j] (h[j]第j个干草堆为一层在满足上述条件下最小宽度)
显然朴素的遍历是O(n2),会超时;
如果对于j<k,对于后面的阶段i,如果h[j]-sum[j-1]<h[k]-sum[k-1] 那么j一定比k优
因为对于后面的阶段i,如果sum[k-1]-sum[i-1]>=h[k] 即h[k]-sum[k-1]<=-sum[i-1]
那么一定h[j]-sum[j-1]<=-sum[i-1]也成立,即j更小且满足条件,即j比k优
所以我们考虑用单调队列来维护这个性质
var f,s,d,q:array[..] of longint;
n,i,x,h,t:longint; begin
readln(n);
for i:= to n do
begin
read(x);
s[i]:=s[i-]+x;
end;
q[]:=n+;
h:=;
t:=;
for i:=n downto do
begin
while (h<t) and (s[q[h+]-]-s[i-]>=d[q[h+]]) do inc(h);
d[i]:=s[q[h]-]-s[i-];
f[i]:=f[q[h]]+;
if i= then break;
while (h<t) and (d[i]-s[i-]<d[q[t]]-s[q[t]-]) do dec(t);
inc(t);
q[t]:=i;
end;
writeln(f[]);
end.