ARC 066 E Addition and Subtraction Hard - 貪心
阿新 • • 發佈:2018-11-10
給一個只有加減的表示式新增括號使得值最大。
若最小?直接把所有減號後面的一串加號括起來即可。
最大?對於一個減號,括起來之後裡面東西相當於最小的問題可以貪心,因此可以dp。
這樣每個括號都是形如S-(A-B)的形式,其中A是從括號開始的一坨加法,B是剩下的東西的絕對值。
事實上可以繼續觀察到形如S-(A-B)+C-(D-E),可以改為S-(A-(B+C)-D-E)=S-A+B+C+D+E,比原來優秀一個D。
因此只有至多一對最外面的括號是有意義的。在這種情況下顯然要麼不延伸,要麼向右延伸最遠比較好(因為其相當於把除了一開始的一串加號減去以外,後面的都可以邊做加法)。
#include <bits/stdc++.h>
#define gc getchar()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define db double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
const int N=100010;lint ps[N],ss[N];int a[N],sg[N],R[N];
inline lint S(int l,int r) { if(l>r) return 0;return ss[r]-ss[l-1]; }
int main()
{
int n=inn();a[1]=inn(),ps[1]=a[1],ss[1]=a[1];
for(int i=1;i<n;i++)
{
while((sg[i]=gc)!='+'&&sg[i]!='-');a[i+1]=inn();
if(sg[i]=='+') ps[i+1]=ps[i]+a[i+1];
else ps[i+1]=ps[i]-a[i+1];ss[i+1]=ss[i]+a[i+1];
}
R[n]=n;lint ans=ps[n];for(int i=n-1;i;i--) if(sg[i]=='+') R[i]=R[i+1];else R[i]=i;
rep(i,1,n-1) if(sg[i]=='-')
ans=max(ans,ps[i]-S(i+1,R[i+1])+ss[n]-ss[R[i+1]]);
return !printf("%lld\n",ans);
}