zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 90 (Rated for Div. 2) D. Maximum Sum on Even Positions(dp)

    题目链接:https://codeforces.com/contest/1373/problem/D

    题意

    给出一个大小为 $n$ 的数组 $a$,下标为 $0 sim n - 1$,可以进行一次反转一个区间中元素的操作,问偶数下标元素的最大和,

    题解

    如果反转区间长度为奇数,则下标奇偶性不同的元素间不会互换,所以反转的区间长度为偶数,反转后的区间可以看作相邻元素两两交换所得。

    如:1 2 3 4 反转后为 4 3 2 1,偶数下标元素由 1 3 变成了 2 4 ,可以看作 1 与 2 相交换,3 与 4 相交换。

    枚举反转区间左端点的奇偶性:

    • 左端点为偶数,对于每个子区间 [i, i + 1],反转后的收益为 $a_{i +1} - a_i$
    • 左端点为奇数,对于每个子区间 [i, i + 1],反转后的收益为 $a_{i} - a_{i+1}$

    所需反转的总区间即为加起来收益最大的一些连续子区间。

    代码

    #include <bits/stdc++.h>
    using ll = long long;
    using namespace std;
    
    void solve() {
        int n; cin >> n;
        int a[n] = {};
        for (int i = 0; i < n; i++)
            cin >> a[i];
        ll mx = 0, al = 0, ar = 0;
        for (int st : {0, 1}) { //枚举反转区间左端点的奇偶性
            ll sum = 0, l = st, r = st; // sum 是以当前子区间结尾的最大收益,[l, r] 是该最大收益所在的区间
            for (int i = st; i + 1 < n; i += 2) {
                int val = (st == 0 ? a[i + 1] - a[i] : a[i] - a[i + 1]); //当前子区间的收益
                if (sum > 0) { //如果之前区间的收益大于0
                    sum += val;
                    r = i + 1;
                } else {
                    sum = val;
                    l = i; 
                    r = i + 1;
                }
                if (sum > mx) {
                    mx = sum; 
                    al = l, ar = r;
                }
            }
        }
        reverse(a + al, a + ar + 1);
        ll ans = 0;
        for (int i = 0; i < n; i += 2)
            ans += a[i];
        cout << ans << "
    ";
    }
    
    int main() {
        int t; cin >> t;
        while (t--) solve();
    }
  • 相关阅读:
    一名中国联络官的来信
    中国女性出席1899年伦敦世界妇女大会
    曾在九江同文任教的中外人士若干
    金韵梅大夫略传
    为何高于四次的方程没有根式解?
    日军进攻九江的影像资料
    美以美会在九江
    九江同文中学与宝洁公司的甘布尔家族
    九江生命活水医院
    微信小程序获取用户信息签名解密C#
  • 原文地址:https://www.cnblogs.com/Kanoon/p/13196946.html
Copyright © 2011-2022 走看看