Problem A sum
给出$n$个元素的序列$\{a_i\}$,求出两个不相交连续子序列的最大元素和。
即对于$1 \leq A \leq B \leq C \leq D \leq n$最大化 $\sum\limits_{i=A}^B a_i + \sum\limits_{i=C}^D a_i $
对于$100\%$的数据满足 $1 \leq n \leq 10^5$ , $0 \leq |a_i| \leq 10^9$
Sol: 考虑一个$O(n^2)$暴力,枚举分割点,左右各求一遍最大连续字段和,然后相加求max。
显然,上述做法内层$O(n)$的枚举没有必要,我们可以均摊$O(1)$求出前缀、后缀最大连续字段和。
于是上述暴力算法可以优化到$O(n)$
# include <bits/stdc++.h> # define int long long using namespace std; const int N=1e5+10; int a[N],n,f[N],b[N]; signed main() { scanf("%lld",&n); for (int i=1;i<=n;i++) scanf("%lld",&a[i]); int Max=-0x3f3f3f3f,ret=0; for (int i=1;i<=n;i++) { if (ret<0) ret=0; ret+=a[i]; Max=max(Max,ret); f[i]=Max; } Max=-0x3f3f3f3f,ret=0; for (int i=n;i>=1;i--) { if (ret<0) ret=0; ret+=a[i]; Max=max(Max,ret); b[i]=Max; } int ans=-0x3f3f3f3f; for (int i=1;i<=n-1;i++) ans=max(f[i]+b[i+1],ans); printf("%lld\n",ans); return 0; }