先將同符號的每一段存下來,並記錄前後段標號,將正數段總和記錄為tot
開乙個最小堆存每一段的abs值。
每次從堆中取出乙個x
去掉這一段,並將左右的段與之合併再存入堆中,作為撤銷或更改操作。
每次操作都會減少一段,直到段數=k就退出。
#include
#include
#include
#include
#define c (c=getchar())
using
namespace
std;
typedef
long
long ll;
inline
void read(ll &x)
const ll n=1000005;
ll n,m,nn,cnt;
ll a[n],v[n];
ll pre[n],nxt[n];
ll ans,tot;
ll heap[2*n],ma;
ll bk[2*n];
inline ll val(ll i)
inline ll f(ll i)
inline ll swap(ll x,ll y)
inline
void down(ll x)
inline
void det(ll x)
inline
void insert(ll x)
inline
void solve()
else
if (nxt[k]==-1)
else
} } int main()
v[++cnt]=a[1];
for (i=2;i<=nn;i++)
if ((a[i]>0&&a[i-1]>0)||(a[i]<0&&a[i-1]<0)) v[cnt]+=a[i];
else v[++cnt]=a[i];
for (i=1;i<=cnt;i++)
if (v[i]>0) ans+=v[i],tot++;
for (i=1;i<=cnt;i++) pre[i]=i-1,nxt[i]=i+1;
pre[1]=nxt[cnt]=-1;
solve();
printf("%lld\n",ans);
return
0;
}
51Nod 1052 最大M子段和
n個整數組成的序列a 1 a 2 a 3 a n 將這n個數劃分為互不相交的m個子段,並且這m個子段的和是最大的。如果m n個數中正數的個數,那麼輸出所有正數的和。例如 2 11 4 13 5 6 2,分為2段,11 4 13一段,6一段,和為26。刷刷水有益身心健康。不過我還是沒有一眼看出來。考慮...
51Nod1052 最大M子段和
n個整數組成的序列a 1 a 2 a 3 a n 將這n個數劃分為互不相交的m個子段,並且這m個子段的和是最大的。如果m n個數中正數的個數,那麼輸出所有正數的和。例如 2 11 4 13 5 6 2,分為2段,11 4 13一段,6一段,和為26。input 第1行 2個數n和m,中間用空格分隔。...
51nod 1052 最大M子段和
1052 最大m子段和 基準時間限制 2 秒 空間限制 131072 kb 分值 80 難度 5級演算法題 n個整數組成的序列a 1 a 2 a 3 a n 將這n個數劃分為 互不相交的m個子段,並且這m個子段的和是最大的。如果m n個數中正數的個數,那麼輸出所有正數的和。例如 2 11 4 13 ...