题目链接:点击这里
题目大意:
给出
2
2
2 个正整数
n
,
m
(
1
≤
n
,
m
≤
1
0
5
)
n,m(1\le n,m \le 10^5)
n,m(1≤n,m≤105) ,接下去给出
a
1
,
a
2
,
⋯
a
m
(
1
≤
a
i
≤
n
)
a_1,a_2,\cdots a_m(1\le a_i\le n)
a1,a2,⋯am(1≤ai≤n) 你可以把这个序列里所有值为
a
i
a_i
ai 的元素改成
a
j
(
1
≤
i
,
j
≤
m
)
a_j (1\le i,j\le m)
aj(1≤i,j≤m) ,注意
i
i
i 可以等于
j
j
j ,只可以改一次。
求
∑
i
=
1
i
≤
m
−
1
∣
a
i
−
a
i
+
1
∣
\sum\limits_{i=1}^{i\le m-1} |a_i-a_{i+1}|
i=1∑i≤m−1∣ai−ai+1∣ 的最小值
题目分析:
一个结论:
当
a
a
a 为序列
b
b
b 的中位数时,
∑
i
=
1
i
≤
n
∣
a
−
b
i
∣
\sum\limits_{i=1}^{i\leq n}{|a-b_i|}
i=1∑i≤n∣a−bi∣ 最小。
我们知道对
a
[
i
]
a[i]
a[i] 产生贡献的位置只有
a
[
i
−
1
]
,
a
[
i
+
1
]
a[i-1],a[i+1]
a[i−1],a[i+1] 所以我们可以对其桶排
然后尝试每次将
a
[
i
]
a[i]
a[i] 修改为其中位数,然后统计更改对答案的影响,最后去所有修改中的最优答案即可
具体细节见代码:
// Problem: C - Ryouko's Memory Note
// Contest: Virtual Judge - 康复训练02
// URL: https://vjudge.net/contest/485549#problem/C
// Memory Limit: 1024 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<unordered_map>
#define ll long long
#define inf 0x3f3f3f3f
#define Inf 0x3f3f3f3f3f3f3f3f
#define int ll
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
using namespace std;
int read()
{
int res = 0,flag = 1;
char ch = getchar();
while(ch<'0' || ch>'9')
{
if(ch == '-') flag = -1;
ch = getchar();
}
while(ch>='0' && ch<='9')
{
res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
ch = getchar();
}
return res*flag;
}
const int maxn = 1e6+5;
const int mod = 1e9+7;
const double pi = acos(-1);
const double eps = 1e-8;
int n,a[maxn],maxx;
vector<int>g[maxn];
signed main()
{
n = read(),n = read();
for(int i = 1;i <= n;i++) a[i] = read(),maxx = max(maxx,a[i]);
int res = 0,st = 0;
for(int i = 1;i <= n;i++)
{
if(i!=1 && a[i-1]!=a[i]) g[a[i]].push_back(a[i-1]);
if(i!=n && a[i]!=a[i+1]) g[a[i]].push_back(a[i+1]);
if(i != 1) st += abs(a[i]-a[i-1]);
}
res = st;
for(int i = 1;i <= maxx;i++)
{
if(g[i].size() == 0) continue;
sort(g[i].begin(),g[i].end());
int mid = g[i][g[i].size()/2],cur = st;
for(auto it:g[i])
{
cur -= abs(it-i);
cur += abs(it-mid);
}
res = min(res,cur);
}
cout<<res<<endl;
return 0;
}