前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[Poetize6] IncDec Sequence 差分

[Poetize6] IncDec Sequence 差分

作者头像
用户2965768
发布2019-04-18 14:13:36
5210
发布2019-04-18 14:13:36
举报
文章被收录于专栏:wymwymwym

题目描述

给定一个长度为n的数列a1,a2,⋯,an a1​,a2​,⋯,an​,每次可以选择一个区间[l,r] ,使这个区间内的数都加1或者都减1。

请问至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列有多少种。

题解:

dif 表示 a[i]与a[i-1]的差值,将a[1]定为基,则对这个差值组成的数组只要令2到n项都为0,求出最小操作次数以及最后基值a[1]有多少可能。

  对差值连续的两个数, 正数(X)和负数(Y),要通过N = min(X,abs(Y))让其中一方变为0.

    对一个正数(X)要通过N = abs(X)让其变为0.

    对一个负数(Y)要通过N = abs(Y)让其变为0.

   在这个过程,我们发现正数和负数可以抵消。例如对 2 5 1,dif是 3 -4,需要min(3,abs(-4))=3步让其中一个为0,对原数组操作就是5减三变成2.   这时原数组就是2,2,1,而此时dif 差值数组是 0,-1.  这-4抵消了3次变成-1,还要经过1次才行,我们发现abs(-4)-3 =1,于是多试几次得出结论对一个正数(X)和负数(Y)都变成0 需要经过 min(X,abs(Y))+abs(X-Y)==max(X,abs(Y))次.

这个结论从连续的两个数推广到整个差值数组,定义totz是所有正数的和,totf是所有负数的和比较两者最大值即为最小操作次数

那会有多少种可能呢?

从上面看出所有差值为正的和totz与所有差值为负的绝对值的和totf  两种中小者是抵消的次数,最后还剩下 abs(X-Y)次操作是改变整个数列值的操作。例如 totz = 6,totf = 5,5次是可以看作正负抵消,最后一次是确定整个数列的值。又例如上面例子2,5,1

3次抵消变成2,2,1最后一次操作让最后一个数加一是确定整个数列变成2.   也就是说多出的abs(X-Y)次操作可以管也可以不管前面的差分,所以答案就是abs(X-Y)+1

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int a[100005];
int main()
{
	int n,dif;
	ll totz=0,totf=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		if(i>=2){
		dif = a[i]-a[i-1];
		if(dif>0)totz+=dif;
		else totf-=dif;
		}
	}
	printf("%lld\n%lld",max(totz,totf),abs(totz-totf)+1);
	return 0;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年04月07日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目描述
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档