AtCoder Regular Contest 119 E - Pancakes
題目連結:點我點我
Score: points
Problem Statement
We have a pancake tower which is a pile of pancakes. Initially, the -th pancake from the top has a size of . Takahashi, a chef, can do the following operation at most once.
- Choose integers and and turn the
Find the minimum possible ugliness of the tower after the operation is done (or not), defined below:
the ugliness is the sum of the differences of the sizes of adjacent pancakes;
that is, the value , where is the size of the -th pancake from the top.
Constraints
- All values in input are integers.
Input
Input is given from Standard Input in the following format:
Output
Print the minimum possible ugliness of the tower.
Sample Input 1
5 7 14 12 2 6
Sample Output 1
17
If we do the operation choosing and , the pancakes will have the sizes of from top to bottom.
The ugliness here is . This is the minimum value possible; there is no way to achieve less ugliness.
Sample Input 2
3 111 119 999
Sample Output 2
888
In this sample, not doing the operation minimizes the ugliness.
In that case, the pancakes will have the sizes of from top to bottom, for the ugliness of .
Sample Input 3
6 12 15 3 4 15 7
Sample Output 3
19
If we do the operation choosing and , the pancakes will have the sizes of from top to bottom.
The ugliness here is , which is the minimum value possible.
Sample Input 4
7 100 800 500 400 900 300 700
Sample Output 4
1800
If we do the operation choosing and , the pancakes will have the sizes of from top to bottom, for the ugliness of .
Sample Input 5
10 535907999 716568837 128214817 851750025 584243029 933841386 159109756 502477913 784673597 603329725
Sample Output 5
2576376600
給出 n 個數,然後可以旋轉一個區間,使得旋轉後的 a 陣列
\[|a_2-a_1|+|a_3-a_2|+|a_4-a_3|+....+|a_n-a_{n-1}| \]最小
很容易可以發現當旋轉一個區間 \([i, j]\) 時,只有 \(|a[i]-a[i-1]|+|a[j]-a[j+1]|\) 變為了 \(|a[i]-a[j+1]|+|a[j]-a[i-1]|\) ,而中間的並沒有發生改變,所以這個問題只關心端點
看到這些絕對值,不由的想到距離,不妨將其在數軸上做一下分類討論,發現只有:
\[\begin{split} a_{i-1}<a_j<a_i<a_{j+1} \\ a_{i-1}<a_j<a_{j+1}<a_{i} \\ a_{i}<a_{j+1}<a_{i-1}<a_{j} \\ a_{i}<a_{j+1}<a_j<a_{i-1} \\ \end{split} \]這此種情況時,才會使得結果變小;又是一道二位偏序,按左端點排個序,只討論右端點就可以解決問題了;
但是題目還有一個邊界問題 ,但 \(O(n)\) 足夠可以解決
總複雜度 \(O(NlogN)\)
const int N = 3e5 + 5;
ll n, m, _;
int i, j, k;
ll a[N];
struct Seg{
int l, r;
int tag;
Seg(){};
Seg(int l, int r){
tag = 0;
if(l > r){
swap(l, r);
tag = 1;
}
this -> l = l;
this -> r = r;
}
} seg[N];
bool cmp(Seg a, Seg b)
{
return a.l < b.l;
}
signed main()
{
//IOS;
while (~sd(n)) {
rep(i, 1, n) sll(a[i]);
for (int i = 1; i < n; i++) {
seg[i] = Seg(a[i], a[i + 1]);
}
sort(seg + 1, seg + n, cmp);
//for(int i=1;i<n;i++) dbg(seg[i].l), dbg(seg[i].r);
ll maxx = 0, ed[2] = {0, 0};
for(int i = 1; i < n; i++){
int tag = seg[i].tag;
if(ed[tag] == 0){
ed[tag] = seg[i].r;
continue;
}
if(seg[i].r <= ed[tag]){
maxx = max(maxx, 1ll * seg[i].r - seg[i].l);
continue;
}
if(seg[i].r > ed[tag]){
maxx = max(maxx, ed[tag] - seg[i].l);
}
ed[tag] = max(ed[tag], 1ll * seg[i].r);
}
ll ans = 0;
for(int i = 2; i <= n; i++){
ans += abs(a[i] - a[i - 1]);
}
maxx *= 2;
for(int i = 1; i < n; i++){
maxx = max(maxx, abs(a[i] - a[i + 1]) - abs(a[i] - a[n]));
maxx = max(maxx, abs(a[i + 1] - a[i]) - abs(a[i + 1] - a[1]));
}
pll(ans - maxx);
}
//PAUSE;
return 0;
}