zoukankan      html  css  js  c++  java
  • AcWing100 IncDec Sequence

    求出(a)的差分序列(b),其中(b_1 = a_1, b_2 = a_2 - a_1, ... b_n = a_n - a_{n - 1})

    根据题意以及公式可以发现,如果我们想让序列所有的数都一样,那么就是让(b_2, b_3, ... b_n)所有的数全为(0),而(b_1 = a_1),即(b_1)决定着(a)的序列有多少种,其中让(a)序列发生变化,相当对(b_1, b_2, b_3, ... b_{n + 1})任选两个数进行操作,那么有以下几种操作:

    1. 操作(b_i, b_j (2 leq i leq j leq n)),一加一减或者一减一加,用贪心的方面想这种操作可以更快地改变b序列地值,所以我们应该尽可能多的选这种操作。
    2. 操作(b_1, b_j \,\, (2 leq j leq n)),这样只能改变(b_2, b_3, ... b_n)中地一个数。
    3. 操作(b_i, b_{n + 1}\,\,(2 leq i leq n)),与(2)同理。
    4. 操作(b_1, b_{n + 1}),相当于对整个序列(a)操作,没有什么意义。

    综上,设(b)为正数的和为(p), (b)为负数的和为(q),对于目的(1):用尽可能少的操作使得序列(a)变成一样的数:
    我们可以尽可能多的使用操作(1),然后再使用操作(2,3)都可以,那么答案就是:

    [min(p, q) + |p - q| = max(p, q) ]

    对于目的(2),因为(b_1 = a_1),所以说(b_1)的取值就是(a)序列的取值,所以说我们应该尽可能地使用操作(2)完成(|p - q|)所以说,答案就是:(|p - q| + 1)

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1E5 + 10;
    int n, a[N], b[N];
    
    typedef long long LL;
    
    int main() {
        cin >> n;
        for (int i = 1; i <= n; i++) cin >> a[i];
        for (int i = 1; i <= n; i++) b[i] = a[i] - a[i - 1];
    
        LL p = 0, q = 0;
        for (int i = 2; i <= n; i++) {
            if (b[i] < 0) p += abs(b[i]);
            if (b[i] > 0) q += b[i];
        }
    
        cout << max(p, q) << endl << abs(p - q) + 1 << endl;
    
        return 0;
    }
    
  • 相关阅读:
    Day18-lvs
    mysql日志
    【杂文】我们都有光明的前途(回忆录)
    【杂文】银色的 NOI2020(退役记)
    【杂文】SCOI2020 游记
    【学习笔记】字符串—广义后缀自动机
    【学习笔记】数论、数学—常见定理、结论、性质汇总
    【杂文】随心一记
    【杂文】CSP2019 蒟蒻AFO(假)记
    【模板整合计划】目录
  • 原文地址:https://www.cnblogs.com/ZhengLijie/p/15074045.html
Copyright © 2011-2022 走看看