#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define fst first
#define snd second
#define pb push_back
#define mset(a,v) memset(a,v,sizeof(a))
#define forn(i,a,b) for(int i = a; i<b; i++)
#define SZ(x) (int)x.size()
#define ALL(x) x.begin(),x.end()
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
template <typename T>
using iset = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
#ifdef D
#define debug(x) cout<<x
#else
#define debug(x) //nothing
#endif
const int MAXN = 5003;
struct STree{
int n;
vector<pair<int,int>> st;
STree(int n=0):n(n), st(4*n+5,pair<int,int>{-1000000,-1}) {}
void upd(int k, int l, int r ,int p, pair<int,int> v){
if(l+1==r){ st[k]=v; return; }
int mid = (l+r)/2;
if(mid>p) upd(2*k,l,mid,p,v);
else upd(2*k+1,mid,r,p,v);
st[k]=max(st[2*k],st[2*k+1]);
}
pair<int,int> query(int k, int l, int r, int L, int R){
if(l>=R || r<=L) return pair<int,int>{-1000000,-1};
if(l>=L && r<=R) return st[k];
int mid = (l+r)/2;
return max(query(2*k,l,mid,L,R),query(2*k+1,mid,r,L,R));
}
void upd(int p, pair<int,int> v){ upd(1,0,n,p,v); }
pair<int,int> query(int l, int r){ return query(1,0,n,l,r); }
};
int n;
ll ps[MAXN];
//vector<vector<vector<int>>> dp;
/*int f(int i, int j, int k){
int &res = dp[i][j][k];
if(res!=-1) return res;
res=-100000000;
ll act = ps[i]-ps[j];
ll ant = ps[j]-(k-1>=0?ps[k-1]:0);
if(i==n){
if(act>=ant) res=1;
else res=-100000000;
//cout<<i<<" "<<j<<" "<<k<<" "<<act<<" "<<ant<<" "<<res<<'\n';
return res;
}
//if(act>=ant) res=max(res,f(i+1,i,(j+1==i?j:j+1))+1);
if(act>=ant) res=max(res,f(i+1,i,j+1)+1);
res=max(res,f(i+1,j,k));
//cout<<i<<" "<<j<<" "<<k<<" = "<<res<<'\n';
return res;
}
vector<ll> recu;
void rec(int i, int j, int k){
int res = f(i,j,k);
ll act = ps[i]-ps[j];
ll ant = ps[j]-(k-1>=0?ps[k-1]:0);
//cout<<i<<" "<<j<<" "<<k<<"= "<<res<<'\n';
if(i==n){
if(act>=ant && res == 1) recu.pb(act);
else recu.pb(-100000000);
return;
}
//if(act>=ant) res=max(res,f(i+1,i,(j+1==i?j:j+1))+1);
if(act>=ant && res==f(i+1,i,j+1)+1) recu.pb(act), rec(i+1,i,j+1);
else if(res==f(i+1,j,k)) rec(i+1,j,k);
}*/
STree dp[MAXN];
int main(){
cin>>n;
forn(i,0,n+2) dp[i]=STree(n+2);
forn(i,1,n+1) cin>>ps[i];
ps[0]=0;
forn(i,2,n+1) ps[i]+=ps[i-1];
//cout<<"Update base\n";
forn(i,1,n+1) dp[i].upd(n,{1,n});
//cout<<"calculo dp\n";
int l,r,mid;
for(int i = n; i>=1; i--){
for(int j = n-1; j>=i; j--){
l = 1; r=n;
while(l<=r){
mid = (l+r)/2;
//cout<<mid<<" "<<l<<" "<<r<<'\n';
if(ps[mid]-ps[j]>=ps[j]-ps[i-1]) r=mid-1;
else l = mid+1;
}
//cout<<i<<" "<<j<<" "<<j+1<<" "<<l<<'\n';
if(l<=n) dp[i].upd(j,{dp[j+1].query(l,n+1).fst+1,j});
}
}
cout<<dp[1].query(1,n+1).fst<<'\n';
return 0;
}