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:至少多少次操作能使数列所有数都一样?

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

方案一:

b1+1,bi-1

b1-1,bi+1

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

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

bi+1,bj-1

bi-1,bj+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;
}
相关推荐
JieE2129 小时前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack2017 小时前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树18 小时前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2121 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2121 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术2 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦2 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
用户497863050732 天前
(一)小红的数组操作
算法·编程语言
怕浪猫2 天前
Electron 系列文章封面图
算法·架构·前端框架