-
示例
输入
3
3
5 -2 3
4
0 0 0 0
3
1 2 3
输出
3
0
3 -
分析
首先能发现如果对ai操作,那会对ai-1,ai,ai+1,三个数造成影响
当ai>0时,对ai操作,则会发生变化:ai-1 + ai, ai - 2ai, ai+1 + ai
如果ai<0,对ai操作,则会发生变化:ai-1 - (-ai), ai + 2(-ai), ai+1 - (-ai)
化简一下,也就是ai-1 + ai, ai - 2ai, ai+1 + ai,计算方式其实和ai>0是一致的
ai-1 => ai-1 + ai
ai => ai - 2ai
ai+1 => ai+1 + ai
然后我们能发现前缀和会发生一些变化
原来
si-1 = s前 + ai-1
si = s前 + ai-1 + ai
si+1 = s前 + ai-1 + ai + ai+1
现在
si-1’ => s前 + ai-1 + ai = si
si’ => s前 + (ai-1 + ai) + (ai - 2ai) = si-1
si+1’ => s前 + (ai-1 + ai) + (ai - 2ai) + (ai+1 + ai) = si-1
从中可以看出,对ai进行操作,除了可以看成直接对ai-1,ai,ai+1这三个数造成影响外,也可以看成就是交换了si-1和si而已,显然后面的两数交换看起来更简单一点
然后我们再看题目要求
求所有ai中绝对值最大值的最小值
而ai我们可以看成是si - si-1
也就是说我们要让两两前缀和之间最大的差值最小
如何能让让两两前缀和之间最大的差值最小呢?
题目中的对ai操作转换到si-1和si交换上,那比如si和sj(i,j不相邻)差值很小,那我们就想办法让这两个数相邻(除了题目说的边界不能操作,中间的任意si和sj都可以交换到相邻的,相当于冒泡,两两相邻的交换,最终就能实现两个不相邻的数进行交换的效果),这样能使得局部si - si-1的值小,这里就是贪心策略,如果所有的si - si-1的值都尽量小,那si - si-1的最大值也会尽量小
所以我们要尽可能让前缀和单调,这样才能让所有的si-si-1尽量小
那直接对前缀和数组排序就行了,排序就单调了,然后在排好序的前缀和数组里,两两相减,找到那个最大的si-si-1
但是,题目说了只能对a2到an-1操作,也就是说在边缘的s1能和s2交换,但是sn-1和sn交换不了,其实也就是sn是固定的,因为sn-1还能和sn-2交换
我们最终要求的是ai的绝对值的最大值,注意ai包括a1,a1=s1-s0,要对s0附值为0,a1不能操作,那s0也是固定的
现在得到所有前缀和中,只有s0和sn固定不能动
s0和sn固定说明即使排完序之后,它两也必须在下标为0和n的位置,即,排完序后必须恢复s0和sn这两个不能动的位置
(s0不一定小于sn,但是其实两种情况类似的,若s0>sn,那就把下图的s0和s5交换位置,由原来的s0到s5改变为从s5最终到s0,s之间的差值不变就行,我们最终的答案只要求差值的最大值。但是为了方便,还是当s0>sn时交换一下使s0是小的那一个)
其实从s0到sn除了下面黄色这种路线,还有可能是绿色这种路线,为什么不选绿色?
因为s0-sn这个高度里,绿色线段有3条,而黄色线段只有一条,如果这个高度里有三个点,那对于黄路线来说这三个点只能集中放在一条线段上,那它们之间,以及和s0-sn高度外的点的差值都不会很大
而对于绿色路线,这三个点要被放在三条线段上,它们和s0-sn高度外的点的差值肯定会更大,,如果把三个点只放在其中一条线段中,这三个点两两相邻的差值是不大,但是,另外两条线段就完完全全作为差值了
然后我们考虑一下具体的走法,比如说上图如果在s0到s4的这个高度里还有好几个值,那到底是放在s0到s4这段里,还是放在s4到s0平行过来的交点这段里
按照下图左边这种全放s0到s4这段里,那s4和下一个数的差值就会很大,显然不能这样做,按照右边这种才更合理,尽量使得两两之间的差值更小,也就是尽量将数均匀地分配到整条线上