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();
    }
  • 相关阅读:
    spring boot1
    部署 OpenStack VirtualBox
    SecureCRT连接虚拟机(ubuntu)配置
    深度优先算法和广度优先算法
    网上学习编程的七个趋势
    AI方向
    sql
    PyQt4入门
    “贪吃蛇”
    SecureCRT 专题
  • 原文地址:https://www.cnblogs.com/Kanoon/p/13196946.html
Copyright © 2011-2022 走看看