给定n个数字,将它们分成连续的若干个区间。满足后一个区间中的数字之和一定不大于前一个区间中的数字之和。
求最多可以分成多少个区间。
除了f[ i] ,再记一个 g[i] ,表示最大序列和( 以i结尾)
f [i] =max( f[j]+1) , j<i , g [j] < s[i]-s[j]
#include <iostream> #include <algorithm> #include <queue> #include <cstring> using namespace std ; const int N =1e6+10; int n,f[N],g[N]; int a[N],s[N]; int hh,tt,q[N*4]; void solve(){ int i,j; cin>>n; for(i=n;i>0;i--)cin>>a[i]; for(i=1;i<=n;i++) s[i]=s[i-1]+a[i]; hh=1,tt=0; q[++tt]=0; int last=0; for(i=1;i<=n;i++){ while(hh<=tt&&s[i]>=g[q[hh]]+s[q[hh]]) last=q[hh],hh++; f[i]=f[last]+1; g[i]=s[i]-s[last]; while(hh<=tt&&g[i]+s[i]<g[q[tt]] +s[q[tt]]) tt--; q[++tt]=i; } cout<<f[n]<<endl; } signed main(){ solve(); }