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

    题目link:https://www.acwing.com/problem/content/102/

    对于此题,因为每个数都比较的大,所以差分进行处理。

    设原数组为 $a[i]$ ,差分后数组为 $d[i]$ $=$ $a[i]$ $-$ $a[i$ $-$ $1]$。

    则容易得出原题转换为:

    • 给定一个数组 $d$,有下面两个操作:
    1. 将 $d[l]$ $+$ $1$ ,$d[r$ $+$ $1]$ $-$ $1$;
    2. 将 $d[l]$ $-$ $1$ ,$d[r$ $+$ $1]$ $+$ $1$;
    • 求最少操作次数使得 $d[2]$ ~ $d[n]$ 全部变为 $0$ ,以及 $d[1]$ 的可能值的数量

    设 $cntx$ 表示 $d$ 数组中的正数之和, $cnty$ 表示 $d$ 数组中负数之和。

    根据贪心原理,容易得出当上文中第一个操作或第二个操作中的两个加减都能使序列更趋近于目标序列的话为最优,只使用其中一个加减为次。

    考虑这个 $cntx$ 和这个 $cnty$ 最终都是要变成 $0$ ,因此可以使用两个操作之一将 $cntx$ 和 $cnty$ 互相抵消,容易得出需要操作 $min(cntx,cnty)$ 次。但当其中一方为 $0$ 时,另一方只能使用半个操作。

    假设此时序列中除了 $0$ 就是负数,而第 $i$ 位为 $-1$ ,那么可以取 $l$ $=$ $i$ , $r$ $=$ $n$ 进行操作一或 $l$ $=$ $1$ , $r$ $=$ $i$ $-$ $1$ 进行操作二,最后不为 $0$ 的一方就用这种方法清 $0$ ,容易得出需要操作 $|cntx$ $-$ $cnty|$ 次。

    此时题中第一问已经解决,考虑第二问。

    $d[1]$ 的可能取值只与后面 $cntx$ 或 $cnty$ 为 $0$ 时进行的操作会改变。假设每次都是取 $l$ $=$ $1$ 然后要更新的数 $i$ 取 $r$ $=$ $i$ $-$ $1$ ,那么 $d[1]$ 的值就会改变一次。最多改变次数就为 $|cntx$ $-$ $cnty|$,但因为也可以不变(取 $l$ $=$ $i$,$r$ $=$ $n$ 操作)。所以 $d[1]$ 的可能值数量就为 $|cntx$ $-$ $cnty|$ $+$ $1$;

    因此本题答案为:

    • 第一问:$min(cntx,cnty)$ $+$ $|cntx$ $-$ $cnty|$ $=$ $max(cntx,cnty)$(至于这个$max$,很容易推出来,或者直接整体法考虑问题也可以不用前面的 $min$ $+$ 绝对值 导);
    • 第二问:$|cntx$ $-$ $cnty|$ $+$ $1$;

    代码把公式套进去就行了(别忘了会爆 $int$):

     1 #include <bits/stdc++.h>
     2 #define INF 0x3f3f3f3f
     3 #define ll long long
     4 using namespace std;
     5 int n, a[100010], d[100010];
     6 ll cntx, cnty;
     7 int main()
     8 {
     9     scanf("%d", &n);
    10     for(int i = 1; i <= n; ++i)
    11         scanf("%d", &a[i]), d[i] = a[i] - a[i - 1];
    12     for(int i = 2; i <= n; ++i)
    13         cntx += (d[i] > 0) * d[i], cnty -= (d[i] < 0) * d[i];
    14     printf("%lld
    %lld", max(cntx, cnty), abs(cntx - cnty) + 1);
    15     return 0;
    16 }
  • 相关阅读:
    Gogs http和ssh地址显示localhost的问题
    SQL Server从读写频繁的大表中删除大批量数据
    Java Spring Boot: Unable to determine jdbc url from datasource
    NPOI导入Excel日期格式的处理
    手把手教你整合最优雅SSM框架
    JDBC链接数据库MySQL 8.0 Public Key Retrieval is not allowed 错误的解决方法
    Vim 入门教程
    jquery.i18n.properties前端国际化方案
    生产者消费者模式中条件判断是使用while而不是if
    ThreadPoolExecutor 中的 shutdown() 、 shutdownNow() 、 awaitTermination() 的用法和区别
  • 原文地址:https://www.cnblogs.com/qqq1112/p/14295512.html
Copyright © 2011-2022 走看看