【ACwing 100】InDec序列——差分
(题面来自AcWing)
给定一个长度为 n 的数列 a1,a2,…,an,每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一。
求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少种。
输入格式
第一行输入正整数n。
接下来n行,每行输入一个整数,第i+1行的整数代表ai。
输出格式
第一行输出最少操作次数。
第二行输出最终能得到多少种结果。
数据范围
0<n≤105,
0≤ai<2147483648(因为不开long long再次见到了祖宗)
看到题面之后的第一想法是差分之后暴搜方案,每次从(1~n + 1)选不同的两个数+1/-1,目标状态是d_2~d_n全部为0。然而数据范围显然不能接受。考虑序列操作的本质:我们要将差分序列d中除第一项外全部变为0,显然最优的方案是在d_2~d_n中优先选择一个负数、一个正数,分别+1、-1;设p、q分别为d中正、负项之和的绝对值,那么如上的第一种操作会把p、q中较小的一方降为0,这个过程最多执行min(p, q)次。之后正/负项中有一方会有剩余,我们可以选择把d_1与剩余项一同操作(相当于把原序列的某个前缀全部+1/-1),也可以选择d_(n+1)与剩余项一同操作(相当于操作后缀),最终都可以实现d_2~d_n全部为0。这一步操作最多执行|p - q|次。那么总的操作次数ans1满足:
ans1 = min(p, q) + |p - q| = max(p, q)
第二问要求统计在满足最小步数的情况下,可能产生的序列种类。由于最后序列每一项都相同,而d[1] = a[1],我们只要考虑最后d[1]有多少种即可。显然,上述最短操作过程不分先后,并且第一种操作不会对d[1]产生影响。考虑执行第二种操作后d[1]可能的取值:d[1]最多被增加/减少|p - q|次,最少被操作0次,并且d[1]可以被操作[0, |p - q|]中的任意多次。因此d[1]的取值有|p - q| + 1种,即ans2 = |p - q| + 1。
代码:
- #include <cstdio>
- #include <iostream>
- #include <cmath>
- #define rep(i, a, b) for(int i = a; i <= b; ++i)
- #define per(i, b, a) for(int i = b; i >= a; --i)
- #define maxn 100010
- using namespace std;
- long long d[maxn], a[maxn];
- int main() {
- int n;
- ios::sync_with_stdio(0);
- cin >> n;
- long long p = 0, q = 0;
- rep(i, 1, n) {
- cin >> a[i];
- d[i] = a[i] - a[i - 1];
- if (i - 1)
- d[i] >= 0 ? p += d[i] : q += -d[i];
- }
- cout << max(p, q) << endl << abs(p - q) + 1;
- return 0;
- }
【ACwing 100】InDec序列——差分的更多相关文章
- AcWing 100. 增减序列
给定一个长度为n的数列每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一. 求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少 ...
- IncDec序列:差分+贪心
IncDec序列 题目描述: 给定一个长度为 n 的数列 a1,a2,…,an,每次可以选择一个区间[l,r],使下标在这个区间内的数都加一或者都减一. 求至少需要多少次操作才能使数列中的所有数都一样 ...
- [leetcode]1109. 航班预订统计(击败100%用户算法-差分数组的详解)
执行用时2ms,击败100%用户 内存消耗52.1MB,击败91%用户 这也是我第一次用差分数组,之前从来没有碰到过,利用差分数组就是利用了差分数组在某一区间内同时加减情况,只会改变最左边和最右边+1 ...
- AcWing:146. 序列(小根堆 + 数学归纳 + 贪心)
给定m个序列,每个包含n个非负整数. 现在我们可以从每个序列中选择一个数字以形成具有m个整数的序列. 很明显,我们一共可以得到nmnm个这种序列, 然后我们可以计算每个序列中的数字之和,并得到nmnm ...
- Acwing-100-IncDec序列(差分)
链接: https://www.acwing.com/problem/content/102/ 题意: 给定一个长度为 n 的数列 a1,a2,-,an,每次可以选择一个区间 [l,r],使下标在这个 ...
- 100 IncDec序列
IncDec序列 Description 给定一个长度为 n 的数列 a1,a2,-,an,每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一. 求至少需要多少次操作才能使数列中 ...
- 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
// test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...
- AcWing 1277. 维护序列
#include <bits/stdc++.h> #define ll long long #define N 4000010 using namespace std; ll t[N],a ...
- 剑指offer41:所有和为S的连续正数序列,例如,有多少种连续的正数序列的和为100
1 题目描述 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久 ...
随机推荐
- (or type Control-D to continue):
(or type Control-D to continue): 很多小伙伴学习使用Linux时可能经常遇到这个问题 (大部分原因是磁盘挂载等问题) 如下图: 具体解决方法 1.直接输入root用户的 ...
- 【Flutter 1-5】运行Flutter的第一个项目——计数器
创建项目 创建Flutter项目有很多种方法,各个IDE工具也都集成了创建Flutter项目的快捷操作.我们这里列举三种方式:使用命令行创建.使用Android Studio创建和使用VSCode创建 ...
- ModelSerializer 高级使用
前言 ModelSerializer中还具有一些高级用法,如批量更新.批量删除.批量创建等. 但是批量过来的数据格式都需要与前端做好协商,什么样的数据格式是单条操作,什么样的数据格式是批量操作. 如下 ...
- STM32移植FreeRTOS(1)
"STM32F103VET6<_>FreeRTOS" 1.项目功能实现 1)LED灯定时闪烁 2)KEY按键检测 3)FreeRTOS任务创建 4)串口输出程序运行状态 ...
- 基于gin的golang web开发:模型验证
Gin除了模型绑定还提供了模型验证功能.你可以给字段指定特定的规则标签,如果一个字段用binding:"required"标签修饰,在绑定时该字段的值为空,那么将返回一个错误.开发 ...
- MapStruct 解了对象映射的毒
前言 MVC模式是目前主流项目的标准开发模式,这种模式下框架的分层结构清晰,主要分为Controller,Service,Dao.分层的结构下,各层之间的数据传输要求就会存在差异,我们不能用一个对象来 ...
- python爬虫04 Requests
接下来我们要来玩一个新的库 这个库的名称叫做 Requests 这个库比我们上次说的 urllib 可是要牛逼一丢丢的 毕竟 Requests 是在 urllib 的基础上搞出来的 通过它我们可以用更 ...
- 5Flask数据库
video 43 安装mysql video44 SQLALchemy连接
- Tim Urban:如何选择真正适合你的职业?
Wait But Why是一个专注于写长博客的网站,Tim Urban是网站的创始人之一.Tim Urban专注于写长论文,与时下的轻度阅读完全背道而驰,文章动辄几千甚至上万字,但令人吃惊的是却拥有惊 ...
- JAVA基础之接口与内部类
接口与内部类 目录 接口与内部类 1. Lambda表达式 1. 关于懒计算 2. Predicate接口 3. 关于方法引用 4. 关于构造器引用 5. 关于变量的作用域 2. 内部类 1. 局部内 ...