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;
}
相关推荐
和光同尘@1 分钟前
66. 加一 (编程基础0到1)(Leetcode)
数据结构·人工智能·算法·leetcode·职场和发展
CHEN5_022 分钟前
leetcode-hot100 11.盛水最多容器
java·算法·leetcode
songx_995 分钟前
leetcode18(无重复字符的最长子串)
java·算法·leetcode
max5006001 小时前
实时多模态电力交易决策系统:设计与实现
图像处理·人工智能·深度学习·算法·音视频
其古寺1 小时前
贪心算法与动态规划:数学原理、实现与优化
算法·贪心算法·动态规划
rit84324992 小时前
基于灰狼算法(GWO)优化支持向量回归机(SVR)参数C和γ的实现
c语言·算法·回归
蒋士峰DBA修行之路2 小时前
实验五 静态剪枝
数据库·算法·剪枝
蒋士峰DBA修行之路2 小时前
实验六 动态剪枝
数据库·算法·剪枝
饭碗的彼岸one2 小时前
C++设计模式之单例模式
c语言·开发语言·c++·单例模式·设计模式·饿汉模式·懒汉模式
Tim_102 小时前
【算法专题训练】20、LRU 缓存
c++·算法·缓存