• 增减序列


     

     贪心加差分,不愧是拔高的题目,好题

    主要有一点不好理解,为什么最终所有可能的序列是abs(pos - neg) + 1种

    pos和neg中的小者就是b[i]和b[j]一正一负配对时+1-1操作的数量
    剩余的|pos-neg|就是落单的差分序列中的正数或负数b[k],这些差分序列剩余的正数或负数b[k]可以通过与差分序列

    中b[1]或b[n+1]进行+1-1操作使b[k]逐步变到0,而这些b[k]如果与b[1]配对进行+1-1的操作则会影响常数列的初值a[1],

    从而影响最终的常数列。所以常数列的最多可能有|p-q|+1种(算上前面min(neg,pos)次不影响常数列初值的操作),最少可能有

    1种,就是差分序列中剩余的b[k]都与b[n+1]配对进行+1-1的操作,也就是一次也不和b[1]配对

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N = 100010;
     5 int a[N];
     6 int main() {
     7     int n;
     8     cin >> n;
     9     for (int i = 1; i <= n; i++) { //读入原数组
    10         cin >> a[i];
    11     }
    12     for (int i = n; i > 1; i--) { //把a数组变为它自己的差分数组
    13         a[i] -= a[i - 1];
    14     }
    15     ll pos = 0; //存储所有正数的和
    16     ll neg = 0; //存储所有负数的和
    17     for (int i = 2; i <= n; i++) {
    18         if (a[i] > 0) {
    19             pos += a[i];
    20         } else {
    21             neg -= a[i]; //注意此时的a[i]是负数,所以此处是减等。如果写加等,最后需要neg=abs(neg)
    22         }
    23     }
    24     //neg = abs(neg); //若上面写+=,此处需要取消注释
    25     cout << min(pos, neg) + abs(pos - neg) << endl; //操作次数
    26     cout << abs(pos - neg) + 1 << endl; //方案数
    27     return 0;
    28 }
  • 相关阅读:
    SQL Server 2008R2 附件数据库问题记录
    关于.NET C#调用Sqlite的总结二
    关于.NET C#调用Sqlite的总结一
    MS Server中varchar与nvarchar的区别
    Intellij IDEA中使用Debug调试
    使用idea关联mysql时报错Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezon'
    学Redis这篇就够了
    java的动态代理机制详解
    mybatis-sql执行流程源码分析
    mybatis
  • 原文地址:https://www.cnblogs.com/fx1998/p/13924720.html
Copyright © 2020-2023  润新知