Educational Codeforces Round 90 (Rated for Div. 2)D.Maximum Sum on Even Positions 傳送門
題意:在原有基礎的數組上,可以反轉一次數組,使得偶數上的和最大。
題解:注意到只可以翻轉一次,故可以理解成求最大子序列翻轉後最大。
可以注意到,如果開始端點是偶數且翻轉長度也爲偶數或開始端點是奇數且翻轉長度也爲奇數時,翻轉一次是無意義的;故翻轉只能考慮開始端點和結束端點奇偶不同時。
預處理奇數位-相鄰偶數位(貢獻≥0),前綴和求出最大連續子序列和,
ans=最大連續子序列和+奇數位和
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
int main()
{
ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
int t;cin>>t;
while(t--)
{
ll n,ans=0,sum=0;cin>>n;
vector<ll>a(n+5,0),x(n+5,0),y(n+5,0),f(n+5,0),q(n+5,0);
for(ll i=1;i<=n;i++)
{
cin>>a[i];
if(i&1)sum+=a[i];
}
for(ll i=2;i<=n;i+=2)
{
x[i]=a[i]-a[i-1];
y[i]=a[i]-a[i+1];
}
for(ll i=2;i<=n;i+=2)
{
f[i]=max(0ll,f[i-2]+x[i]);
q[i]=max(0ll,q[i-2]+y[i]);
}
for(ll i=2;i<=n;i+=2)
ans=max(ans,f[i]);
for(ll i=2;i<=n-1;i+=2)
ans=max(ans,q[i]);
cout<<ans+sum<<endl;
}
return 0;
}