题解:CF2274B Prefix

· · 题解

题目传送门

题目描述

给定长为 N 一个数组 A,对于每一个 i 记 sum 为 A_1 到 A_{i-1} 的前缀和,你可以将 A_i 变成 A_i,A_i+sum,A_i-sum 中的其中一个,求操作完后整个数组的最大值。

解法描述

不难发现对于每一个 A_i,它对答案的贡献就是它进行三种操作过后的最大值。

如果选择 $A_i+sum$,那么 $sum$ 更大答案更优,反之亦然。 所以我们可以分别维护一个前缀最大值和一个前缀最小值,并在维护过程中统计答案。 顺带一提,稍微推一下柿子就可以发现维护 $sum$ 时 $sum$ 的取值也只有 $A_i$,$A_i+sum$,$A_i+sum\times2$ 这三种取值,所以维护过程中不会因为其他因素导致答案变劣。 时间复杂度 $O(N)$。 ### AC Code ```cpp #include<iostream> #include<algorithm> #include<cstring> #include<queue> #define int long long #define endl '\n' using namespace std; int T,N,A[55]; signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>T; while(T--) { cin>>N; for(int i=1;i<=N;i++) { cin>>A[i]; } int sum=A[1],sum2=A[1],ans=A[1]; for(int i=2;i<=N;i++) { ans=max(ans,max({A[i]-sum,A[i],A[i]+sum2})); sum=min({A[i],sum+A[i],sum*2+A[i]}); sum2=max({A[i],sum2+A[i],sum2*2+A[i]}); } cout<<ans<<endl; } return 0; } ``` 那么完结撒花!