当前位置: 首页 > news >正文

D. Not Alone

View Post

D. Not Alone

D. Not Alone

Problem - D - Codeforces

处理一\(b_i = b_{(i+m-2)\bmod m\;+1}\), 或 \(b_i = b_{i\bmod m\;+1}\)

​ 考虑将环分成多块处理,保证块长大于 \(1\)

处理二\(\sum_{i=1}^n |b_i - a_i|\)

​ 由于对于 \(a_i\),操作只有 \(+1\)\(-1\),对于每个块,最小的操作数就是将其变成中位数(中位数定理)。

​ 那么划分成多块操作会超时,我们考虑会不会有更好的策略:

​ 观察一个块内有 \(4\) 个元素:可以拆成两个 \(2\) 个元素的块,这样总会使得结果变小。

​ 同理最终把块拆成 \(2\) 块和 \(3\) 块总会使得答案最好。

​ 如果长度为 \(2\)\(3\)\(cost\) 就是最大值 \(-\) 最小值。

处理三:环

​ 将数组循环移位操作几次,然后在开头断开,断环成链进行计算。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1000000000000000005;ll cost(ll x, ll y){return max(x, y) - min(x, y);
}
ll cost(ll x, ll y, ll z){return max({x, y, z}) - min({x, y, z});
}
void solve(){int n;cin >> n;vector<int> a(n + 1);for(int i = 1;i <= n;i++){cin >> a[i];}auto f = [&]() -> ll{vector<ll> dp(n + 1, 0);dp[0] = 0;dp[1] = INF;for(int i = 2;i <= n;i++){dp[i] = dp[i - 2] + cost(a[i - 1], a[i]);if(i >= 3){dp[i] = min(dp[i], dp[i - 3] + cost(a[i - 2], a[i - 1], a[i]));}}return dp[n];};ll ans = INF;for(int cyc = 0; cyc < 4;cyc++){ans = min(ans, f());for(int i = 2;i <= n;i++){swap(a[i], a[i - 1]);}}cout << ans << "\n";
}int main(){//ios::sync_with_stdio(false);//cin.tie(nullptr), cout.tie(nullptr);int T = 1;cin >> T;while(T--){solve();}return 0;
}