[Poetize6] IncDec Sequence 差分
题目描述
给定一个长度为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;
}
上一篇: 平板电脑怎么装系统 平板电脑怎样装系统
下一篇: 平板电脑怎么连接wifi无线网络教程
推荐阅读
-
100. IncDec序列(差分序列,化区间为单点)
-
100. IncDec序列(差分思想)
-
BZOJ 3043: IncDec Sequence 差分 + 思维
-
bzoj 3043 IncDec Sequence 差分
-
BZOJ3043 IncDec Sequence (差分)
-
AcWing 100. IncDec序列(差分)
-
[Poetize6] IncDec Sequence
-
BZOJ 3043: IncDec Sequence 差分 + 思维
-
[BZOJ]3043: IncDec Sequence 差分
-
洛谷 P4552 [Poetize6] IncDec Sequence【差分+脑洞】