518 字
3 分钟
Blackslex-and-Showering

题面#

After his IMO medalist friend showered for two hours so that “he doesn’t have to shower this again this week,” Blackslex will be late for class!

In order to get to class, Blackslex must take the crowded elevator to many floors in a certain order. Because he is a hacker, he can skip visiting up to one floor without the other people knowing. His time taken is the sum of the absolute differences between consecutive floor numbers. Find the minimum time taken, given that he can skip up to one floor.

More formally, given an array a=[a1,a2,,an]a = [a_1, a_2, \ldots, a_n] of nn integers, you can choose up to one index k{1,2,,n}k \in \{1, 2, \ldots, n\} to erase such that the sum

i=1n2bibi+1\sum_{i=1}^{n-2} |b_i - b_{i+1}|

is minimized, where b=[a1,,ak1,ak+1,,an]b = [a_1, \ldots, a_{k-1}, a_{k+1}, \ldots, a_n] is the array after erasing element aka_k. Report the minimum sum.

Input

The first line contains one integer tt (1t1041 \le t \le 10^4) — the number of test cases.

The first line of each test case contains one integer nn (3n21053 \le n \le 2 \cdot 10^5) — the size of the array.

The second line contains nn integers a1,a2,,ana_1, a_2, \ldots, a_n (1ai1001 \le a_i \le 100).

It is guaranteed that the sum of nn does not exceed 21052 \cdot 10^5 over all test cases.

Output

For each test case, output a single real number — the minimum time taken.

思路#

先计算不删除时的总耗时 S=i=1n1aiai+1S=\sum_{i=1}^{n-1}\lvert a_i-a_{i+1}\rvert

删除一个位置 kk 只会改变与 aka_k 相邻的边 其余项保持不变

进行讨论:

  • k=1k=1k=nk=n 仅移除一条边 得到 S=Sa1a2S'=S-\lvert a_1-a_2\rvertS=San1anS'=S-\lvert a_{n-1}-a_n\rvert\
  • 1<k<n1<k<n 原来经过 aka_k 的贡献为 ak1ak+akak+1\lvert a_{k-1}-a_k\rvert+\lvert a_k-a_{k+1}\rvert 删除后改为跨越边 ak1ak+1\lvert a_{k-1}-a_{k+1}\rvert

因而 S=Sak1akakak+1+ak1ak+1S'=S-\lvert a_{k-1}-a_k\rvert-\lvert a_k-a_{k+1}\rvert+\lvert a_{k-1}-a_{k+1}\rvert
定义节省量 save(k)=SS\mathrm{save}(k)=S-S' 中间位置有 save(k)=ak1ak+akak+1ak1ak+10\mathrm{save}(k)=\lvert a_{k-1}-a_k\rvert+\lvert a_k-a_{k+1}\rvert-\lvert a_{k-1}-a_{k+1}\rvert\ge 0 由三角不等式成立
因此目标等价为最大化 save(k)\mathrm{save}(k) 最终答案为 Smaxksave(k)S-\max_k \mathrm{save}(k)

代码#

#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t --) {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i ++) {
cin >> a[i];
}
long long sum = 0;
for (int i = 0; i + 1 < n; i ++) {
sum += llabs((long long)a[i] - a[i + 1]);
}
long long best = 0;
best = max(best, llabs((long long)a[0] - a[1]));
best = max(best, llabs((long long)a[n - 2] - a[n - 1]));
for (int k = 1; k + 1 < n; k ++) {
long long l = llabs((long long)a[k - 1] - a[k]);
long long r = llabs((long long)a[k] - a[k + 1]);
long long b = llabs((long long)a[k - 1] - a[k + 1]);
best = max(best, l + r - b);
}
cout << (sum - best) << "\n";
}
}
Blackslex-and-Showering
https://github.com/posts/blackslex-and-showering/
作者
FZSGBall
发布于
2026-05-16
许可协议
CC BY-NC-SA 4.0