zoukankan      html  css  js  c++  java
  • 增减序列

     

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

    主要有一点不好理解,为什么最终所有可能的序列是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 }
  • 相关阅读:
    计算机问题:VirtualBox启动崩溃问题
    软件工程:代码静态分析工具
    oracle 游标
    oracle 控制语句
    oracle 数据类型及函数
    oracle 表空间Tablespaces
    java.lang.RuntimeException: java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符
    oracle 用户解锁和修改用户密码
    shiro + maven 的web配置(不整合spring)
    配置shiro错误
  • 原文地址:https://www.cnblogs.com/fx1998/p/13924720.html
Copyright © 2011-2022 走看看