码迷,mamicode.com
首页 > 其他好文 > 详细

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

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

标签:偶数   最大子段和   position   lan   ==   数位   com   完整   tmp   


题意

给定一个下标从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 (最大子段和)

标签:偶数   最大子段和   position   lan   ==   数位   com   完整   tmp   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!