您的位置:首页 > 其它

51 nod 1254 最大子段和 V2(思维)

2017-10-17 20:54 531 查看
1254 最大子段和 V2


题目来源: Codility

基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题


 收藏


 关注

N个整数组成的序列a[1],a[2],a[3],…,a
,你可以对数组中的一对元素进行交换,并且交换后求a[1]至a
的最大子段和,所能得到的结果是所有交换中最大的。当所给的整数均为负数时和为0。
例如:{-2,11,-4,13,-5,-2, 4}将 -4 和 4 交换,{-2,11,4,13,-5,-2, -4},最大子段和为11 + 4 + 13 = 28。

Input
第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)


Output
输出交换一次后的最大子段和。


Input示例
7
-2
11
-4
13
-5
-2
4


Output示例
28


这题只要把公式推出来就很好写了

s[i]等于 i 的后缀和

ans=s[l]-min(l,r,)-s[r+1]+max(r+1)

我们可以从起点开始枚举右端点那么 -s[r+1]+max(r+1) 已知 维护 s[i]-min(l,r)即可

主要是想到后缀和 然后推公式 然后利用公式枚举

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N =2e5+10;
typedef long long LL;
const LL mod = 1e15+7;
LL a
,mx
,s
;
struct node
{
LL v,sum;
}st
;
int n;
LL ans;
void solve()
{
a[n+1]=-mod;
for(int i=n;i>=1;i--)
{
mx[i]=max(mx[i+1],a[i]);
s[i]=s[i+1]+a[i];
}
int k=0;
LL maxt=-mod,now=-mod;
for(int i=1;i<=n;i++)
{
now=max(now,s[i]);
maxt=max(maxt,now-a[i]);
ans=max(ans,maxt-s[i+1]+mx[i+1]);
}
return ;
}

int main()
{
ans=0;
scanf("%d", &n);
for(int i=1;i<=n;i++) scanf("%lld", &a[i]);
solve();
reverse(a+1,a+n+1);
solve();
cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: