首先这道题有一个很重要的贪心就是
在保证所有干草堆都能参与搭建的前提下,我们尽量使最底层的宽度小,这样搭起来的的干草堆高度一定是最高的
当我们以第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优
所以我们考虑用单调队列来维护这个性质

1 var f,s,d,q:array[0..100010] of longint; 2 n,i,x,h,t:longint; 3 4 begin 5 readln(n); 6 for i:=1 to n do 7 begin 8 read(x); 9 s[i]:=s[i-1]+x; 10 end; 11 q[1]:=n+1; 12 h:=1; 13 t:=1; 14 for i:=n downto 1 do 15 begin 16 while (h<t) and (s[q[h+1]-1]-s[i-1]>=d[q[h+1]]) do inc(h); 17 d[i]:=s[q[h]-1]-s[i-1]; 18 f[i]:=f[q[h]]+1; 19 if i=1 then break; 20 while (h<t) and (d[i]-s[i-1]<d[q[t]]-s[q[t]-1]) do dec(t); 21 inc(t); 22 q[t]:=i; 23 end; 24 writeln(f[1]); 25 end.