zoukankan      html  css  js  c++  java
  • Codeforces 1373D


    1373D. Maximum Sum on Even Positions


    题意

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

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

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


    限制

    Time limit per test: 2 seconds

    Memory limit per test: 256 megabytes

    1≤t≤2⋅104

    1≤n≤2⋅105

    1≤ai≤109

    ∑n≤2⋅105




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

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

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

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

    如下图所示

    PIC1

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

    PIC2

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

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

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




    完整程序

    #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
    ",ans+mx);
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
            solve();
        return 0;
    }
    

  • 相关阅读:
    diffstat命令
    v-if与v-show的区别
    常数时间插入、删除和获取随机元素
    diff命令
    C++ bitset的简单使用
    树的直径 | 简答的两道模板题
    Codeforces Round #544 (Div. 3)简单题解
    VIM 入门手册, (VS Code)
    PTA 天梯赛 L3-003 社交集群(并查集)
    L3-002 特殊堆栈 (双数组模拟栈)
  • 原文地址:https://www.cnblogs.com/stelayuri/p/13193747.html
Copyright © 2011-2022 走看看