首页 > 其他 > 详细

Codeforces 1373D - Maximum Sum on Even Positions (最大子段和)

时间:2020-06-26 10:26:12      阅读:147      评论:0      收藏:0      [点我收藏+]

题意

给定一个下标从0开始的数列

最多旋转一次子数列(将某一段子数列倒置)

问所有偶数位置上的元素和的最大值


限制

  • 1≤t≤2?104
  • 1≤n≤2?105
  • 1≤ai≤109
  • ∑n≤2?105



先求出偶数位置上元素和(初值)

可以发现,只有当选中的子数列长度为偶数时才能改变偶数位置上元素和(与奇数位置互换)

因为只涉及到奇偶交换,位置的奇偶性是固定的

所以可以直接看作将某一偶数长度段中,第一个元素与第二个元素互换,第三个与第四个互换,以此类推……

如下图所示

技术分享图片

如果要替换原位置为 2 4 6 8 的元素,则只存在两种方案

技术分享图片

对于每种方案,在原数列中以每两个为一组,以奇数位-偶数位为值

求出最大连续子段和即为替换所能带来的最大收益

加上原本偶数位之和,即为答案




完整程序

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int a[200050];

void solve()
{
    int n;
    scanf("%d",&n);
    ll ans=0;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        if((i&1)==0)
            ans+=a[i]; //原偶数位之和
    }
    ll tmp1=0,tmp2=0,mx=0;
    for(int i=0;i<n;i+=2)
    {
        if(i+1<n) //用i+1替换i
        {
            tmp1+=a[i+1]-a[i];
            mx=max(mx,tmp1); //取大
            if(tmp1<0) //连续子段最大和,如果和小于0,则从0开始计算
                tmp1=0;
        }
        if(i>1) //用i-1替换i
        {
            tmp2+=a[i-1]-a[i];
            mx=max(mx,tmp2);
            if(tmp2<0)
                tmp2=0;
        }
    }
    printf("%lld\n",ans+mx);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
        solve();
    return 0;
}


Codeforces 1373D - Maximum Sum on Even Positions (最大子段和)

原文:https://www.cnblogs.com/stelayuri/p/13193747.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!