• D. Maximum Sum on Even Positions(最大连续字段和)


    Problem - 1373D - Codeforces

    题意:

     

    给你一个由n个整数组成的数组a。数组的索引从零开始(即第一个元素是a0,第二个是a1,以此类推)。

    你最多可以扭转这个数组的一个子数组(连续子段)。回顾一下,a的边框为l和r的子数组是a[l;r]=al,al+1,...,ar

    你的任务是反转这样一个子数组,使所得数组的偶数位置上的元素之和达到最大(即整数k=⌊n-1/2⌋的元素之和应该是最大的)。

    你必须回答t个独立的测试案例。

    输入
    输入的第一行包含一个整数t(1≤t≤2⋅104)--测试案例的数量。然后是t个测试用例。

    测试用例的第一行包含一个整数n(1≤n≤2⋅105)--a的长度。测试用例的第二行包含n个整数a0,a1,...,an-1(1≤ai≤109),其中ai是a的第i个元素。

    保证n的总和不超过2⋅105(∑n≤2⋅105)。

    输出


    例子
    输入复制
    4
    8
    1 7 3 4 7 6 2 9
    5
    1 2 1 2 1
    10
    7 8 4 5 7 6 8 9 7 3
    4
    3 1 2 1


    输出拷贝
    26
    5
    37
    5

    题解:

    如果反转的子数组长度是奇数,对答案无影响,所以我们应该只考虑,偶数的情况,首先我们把偶数位的数相加为最小可能情况

    其次子数组可能以奇数位,或偶数位开头,所以也要分情况

    如果反转,那么对于答案的贡献,相当于奇数位-偶数位的数值

    因为偶数与奇数位的值都会交换位置,我们已经统计了偶数位的值,所以如果相减的结果大于0,就可以看作是对结果的贡献,就继续遍历加上

    当然,也会有小于0的情况,说明从之前某一位开头的,到这的子数组是对答案无贡献的,就把遍历到此的贡献变为0,代表从现在开始的子数组

    途中找贡献的最大值即可

    1. #include<iostream>
    2. #include<algorithm>
    3. using namespace std;
    4. long long a[200050];
    5. int main()
    6. {
    7. int t;
    8. cin >> t;
    9. while(t--)
    10. {
    11. long long s1 = 0,s2 = 0,ma = 0;
    12. int n;
    13. cin >> n;
    14. long long ans = 0;
    15. for(int i =1;i <= n;i ++)/
    16. {
    17. cin >> a[i];
    18. if(i&1)//由于我首位下标从1开始,所以奇数位相加
    19. {
    20. ans += a[i];
    21. }
    22. }
    23. for(int i = 2;i <= n;i +=2)
    24. {
    25. s1 = max((long long)0,a[i] - a[i-1]+s1);
    26. ma = max(ma,s1);
    27. }
    28. for(int i = 3;i <= n;i +=2)
    29. {
    30. s2 = max((long long)0,a[i-1]-a[i]+s2);
    31. ma = max(ma,s2);
    32. }
    33. cout<<ans+ma<<'\n';
    34. }
    35. }

  • 相关阅读:
    Linux安装haproxy
    MySQL之数据库三大范式
    MybatisPlus多数据源
    Maven学习(一)
    【线性系统理论】笔记二-状态转移矩阵+状态运动轨迹
    golang 多个struct 转换融合为一个json,平级融合或者多级融合
    Discourse 的无效附件清理
    原型和原型链
    【Redis】1、NoSQL之Redis的配置及优化
    全都会!预测蛋白质标注!创建讲义!解释数学公式!最懂科学的智能NLP模型Galactica尝鲜 ⛵
  • 原文地址:https://blog.csdn.net/m0_64158084/article/details/127737523