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;
}
相关推荐
CodeSheep程序羊17 分钟前
拼多多春节加班工资曝光,没几个敢给这个数的。
java·c语言·开发语言·c++·python·程序人生·职场和发展
2401_8414956422 分钟前
【LeetCode刷题】二叉树的直径
数据结构·python·算法·leetcode·二叉树··递归
budingxiaomoli22 分钟前
优选算法-字符串
算法
I'mChloe25 分钟前
PTO-ISA 深度解析:PyPTO 范式生成的底层指令集与 NPU 算子执行的硬件映射
c语言·开发语言
qq74223498441 分钟前
APS系统与OR-Tools完全指南:智能排产与优化算法实战解析
人工智能·算法·工业·aps·排程
2的n次方_1 小时前
Runtime 内存管理深化:推理批处理下的内存复用与生命周期精细控制
c语言·网络·架构
嵌入小生0071 小时前
标准IO---核心函数接口延续(嵌入式Linux)
c语言·vscode·vim·嵌入式·小白·标准io·函数接口
A尘埃1 小时前
超市购物篮关联分析与货架优化(Apriori算法)
算法
.小墨迹1 小时前
apollo学习之借道超车的速度规划
linux·c++·学习·算法·ubuntu
不穿格子的程序员1 小时前
从零开始刷算法——贪心篇1:跳跃游戏1 + 跳跃游戏2
算法·游戏·贪心