题目分析:
我们用 F[I] F [ I ] 表示用第 I N I N 包做草堆的时候最底下一层的最短长度, G[I] G [ I ] 记录此时能到达的最高高度,显然可以得到如下的一个状态转移方程:
#include
#include
#include
#include
#include
#define DB double
#define SG string
#define LL long long
#define Fp(A,B,C,D) for(A=B;A<=C;A+=D)
#define Fm(A,B,C,D) for(A=B;A>=C;A-=D)
#define Clear(A) memset(A,0,sizeof(A))
#define Copy(A,B) memcpy(A,B,sizeof(A))
using namespace std;
const LL Max=1e5+5;
const LL Mod=1e9+7;
const LL Inf=1e18;
LL N,F[Max],G[Max],Q[Max],Sum[Max];
inline LL Read(){
LL X=0;char CH=getchar();bool F=0;
while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
return F?-X:X;
}
inline void Write(LL X){
if(X<0)X=-X,putchar('-');
if(X>9)Write(X/10);
putchar(X%10+48);
}
int main(){
LL I,J,K;
N=Read();
Fp(I,1,N,1){
Sum[I]=Sum[I-1]+Read();
}LL Head=1,Tail=1;
Q[1]=N+1;
Fm(I,N,1,1){
while(Head1]-1]-Sum[I-1]>=F[Q[Head+1]]){
++Head;
}F[I]=Sum[Q[Head]-1]-Sum[I-1];G[I]=G[Q[Head]]+1;
while(Head<=Tail&&Sum[Q[Tail]-1]-F[Q[Tail]]<=Sum[I-1]-F[I]){
--Tail;
}Q[++Tail]=I;
}Write(G[1]);
return 0;
}