题目链接:https://codeforces.com/contest/1359/problem/D
题解:这题与典型的求最大子段和相类似,但是多了一个要去除最大的值,再看题目中-30<=ai<=30,因此可以想到去枚举要移除的这个最大值,再通过求最大子段和求出连续区间和最大的值,对于所有的情况取max即可。这边补充一下最大子段和O(N)的求解方法吧,遍历一遍数组只要当和小于0时即可将sum置为0,因为它的贡献<0加上后面的肯定会变小,因此只要扫描一遍数组即可。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int a[maxn];
int main()
{
int n;
cin>>n;map<int,int> mp;
for(int i=0;i<n;i++){
cin>>a[i];
mp[a[i]]=1;
}
int ans=0;
for(int i=-30;i<=30;i++){
if(!mp[i]) continue;
int sum=0;
for(int j=0;j<n;j++){
if(a[j]<=i){
if(sum+a[j]<0) sum=0;
else{
sum+=a[j];
ans=max(ans,sum-i);
}
}
else sum=0;
}
}
cout<<ans;
return 0;
}