vj题单 P4552 [Poetize6] IncDec Sequence

思路:

一次操作:选一个区间[l, r],把这个区间的数都加1或者都减1,可以将求该数列的差分数组b然后来进行该操作

复制代码
一次操作的两种种情况:(l可以等于r)
1.b[l]+1   b[r+1]-1
2.b[l]-1   b[r+1]+1

Q1:至少多少次操作能使数列所有数都一样?

等价于:至少多少次操作可以使b[i](i != 1)等于0?

方案一:

b[1]+1,b[i]-1

b[1]-1,b[i]+1

执行次数:正数的绝对值加负数的绝对值

方案二:让除了b[1]以外的其他正负数相互抵消,最后只剩b[1]和若干项不为0的b的元素

b[i]+1,b[j]-1

b[i]-1,b[j]+1

执行次数:若正数绝对值>负数绝对值,则执行次数为正数绝对值,反之,则为负数绝对值

对比两个方案,显然,后者是最少执行次数

Q2:在保证最少次数的前提下,最终得到的数列有多少种?

等价于:由方案2,我们可以确定最少次数,在得到最终的常数列前,要经过多少个不同的数列?

复制代码
5 0 1 1 -4
5 0 0 1 -3
5 0 0 0 -2  
上述过程代表方案2的处理过程
最后得到5 0 0 0 -2
在得到5 0 0 0 0 前
我们会经过两个数列:
即b[1]-1,b[5]+1  : 4 0 0 0 -1
 b[1]-1,b[5]+1   : 3 0 0 0 0

容易知道:经过的数列数为max(正数绝对值,负数绝对值)-min(正数绝对值,负数绝对值)

笔者答案:
复制代码
#include<stdio.h>
long long a[100001];
int main ()
{
	long long n;
	long long b[100001];
	scanf("%lld",&n);
	long long i;
	for(i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		b[i]=a[i]-a[i-1];
	}
	long long z=0,f=0,max,Abs;
	for(i=2;i<=n;i++)
	{
		if(b[i]>0)
		{
			z+=b[i];
		}
		else
		{
			f+=(-b[i]);
		}
	}
	if(z>f)
	{
		max=z;
		Abs=z-f;
	}
	else
	{
		max=f;
		Abs=f-z;
	}
	printf("%lld\n%lld",max,Abs+1);
	return 0;
}
相关推荐
Fine姐3 分钟前
数据挖掘3.6~3.10 支持向量机—— 核化SVM
算法·支持向量机·数据挖掘
野渡拾光1 小时前
【考研408数据结构-05】 串与KMP算法:模式匹配的艺术
数据结构·考研·算法
tainshuai4 小时前
用 KNN 算法解锁分类的奥秘:从电影类型到鸢尾花开
算法·分类·数据挖掘
Coovally AI模型快速验证9 小时前
农田扫描提速37%!基于检测置信度的无人机“智能抽查”路径规划,Coovally一键加速模型落地
深度学习·算法·yolo·计算机视觉·transformer·无人机
pusue_the_sun9 小时前
数据结构:二叉树oj练习
c语言·数据结构·算法·二叉树
RaymondZhao3410 小时前
【全面推导】策略梯度算法:公式、偏差方差与进化
人工智能·深度学习·算法·机器学习·chatgpt
zhangfeng113310 小时前
DBSCAN算法详解和参数优化,基于密度的空间聚类算法,特别擅长处理不规则形状的聚类和噪声数据
算法·机器学习·聚类
啊阿狸不会拉杆11 小时前
《算法导论》第 32 章 - 字符串匹配
开发语言·c++·算法
小学生的信奥之路11 小时前
洛谷P3817题解:贪心算法解决糖果分配问题
c++·算法·贪心算法
曙曙学编程12 小时前
stm32——GPIO
c语言·c++·stm32·单片机·嵌入式硬件