Submission #1337932

#TimeUsernameProblemLanguageResultExecution timeMemory
1337932JuanJLRastuci (COCI25_rastuci)C++20
42 / 110
242 ms589824 KiB
#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;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...