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
Output
Input示例
Output示例
这题只要把公式推出来就很好写了
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;
}
题目来源: 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;
}
相关文章推荐
- [51Nod](1049)最大子段和 ---- 思维
- 51Nod-1254-最大子段和 V2
- 51 nod 1052 最大M子段和(DP)
- 【循环数组最大子段和】51nod 1050 循环数组最大子段和
- 51 NOD 1188 最大公约数之和 V2(基础数论)
- 51nod 1254 最大子段和 V2 ——单调栈
- 51 nod 1292 字符串中的最大值 V2(后缀数组)
- 51 nod 1188 最大公约数之和 V2(狄利克雷卷积+线性筛法)
- 最大子段和(51Nod 1049)、最小正子段和(51Nod 1065)、总结(最小子段和、最大子段和、最小正子段和)
- 51 nod 1188 最大公约数之和 V2
- 51nod 1254最大子段和V2
- [贪心+堆+链表] 51Nod1053 最大M子段和 V2
- [51nod1254]最大子段和 V2
- 51 nod 1574 排列转换(思维 贪心)
- 1011 最大公约数GCD(51NOD基础题)
- 51nod1081---子段求和(51nod基础:前缀和)
- 【贪心+优先队列】51Nod 1053 最大M子段和 V2
- 51 nod 1421 最大MOD值
- D - 最大子矩阵和 51Nod - 1051
- 51 Nod 1086 背包问题 V2