题面
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 of integers, you can choose up to one index to erase such that the sum
is minimized, where is the array after erasing element . Report the minimum sum.
Input
The first line contains one integer () — the number of test cases.
The first line of each test case contains one integer () — the size of the array.
The second line contains integers ().
It is guaranteed that the sum of does not exceed over all test cases.
Output
For each test case, output a single real number — the minimum time taken.
思路
先计算不删除时的总耗时
删除一个位置 只会改变与 相邻的边 其余项保持不变
进行讨论:
- 若 或 仅移除一条边 得到 或 \
- 若 原来经过 的贡献为 删除后改为跨越边
因而
定义节省量 中间位置有 由三角不等式成立
因此目标等价为最大化 最终答案为
代码
#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"; }}