思路:
先开一个存有动态数组的数组
枚举数列中的每个点充当x,用数组记录下与改元素相邻的元素,用来计算对答案的贡献。下面的问题就是计算x改变后对答案的贡献了,具体的,我们想知道把x改变成什么值才能对答案的贡献最大,自然是该数组中位数了,然后计算ans取小就是最终答案。
#include <cstdio> #include <iostream> #include <algorithm> #include <ios> #include <vector> using namespace std; typedef long long ll; const int N = (int)1e5; int n, m, a[N + 1]; vector<int> b[N + 1]; int main(int argc, char *argv[]) { freopen("note.in", "r", stdin); freopen("note.out", "w", stdout); ios :: sync_with_stdio(false); cin >> n >> m; for (int i = 1; i <= m; ++i) cin >> a[i]; for (int i = 1; i <= m; ++i) { if (i > 1 && a[i - 1] != a[i]) b[a[i - 1]].push_back(a[i]); if (i < m && a[i + 1] != a[i]) b[a[i + 1]].push_back(a[i]); } ll ans = 0LL, sum = 0LL; for (int i = 1; i <= n; ++i) { if (!b[i].size()) continue; sort(b[i].begin(), b[i].end());//把这一串数按从小到大的顺序排起来 int y = b[i][b[i].size() >> 1]; ll before = 0LL, after = 0LL; for (int j = 0; j < b[i].size(); ++j) { before += abs(i - b[i][j]); after += abs(y - b[i][j]); } ans = max(ans, before - after), sum += before; } cout << sum / 2 - ans << endl; fclose(stdin); fclose(stdout); return 0; }