[Codeforces] Codeforces Round #688 (Div. 2) B. Suffix Operations
問題
方針
まず初めに、\( a_1 \) に対して操作する必要はありません。\( a_1 \) に対して操作を行うということは、全ての配列に対して \( 1 \) を加算または減算をするためです。操作の前に配列の値を変えない場合に必要な操作回数 \( b \) は、
\[ b = \sum_{i=1}^{n-1}|a_{i+1} – a_{i}|\]
となります。ここで、配列の値を \( 1 \) つ変えたときの必要な操作回数を考えます。\( a_1 \leftarrow a_2 \) とすると、\( b – |a_2 – a_1| \) となります。また、\( a_n \leftarrow a_{n-1} \) とすると、\( b – |a_{n} – a_{n – 1}| \) となります。\( 2 \leq i \leq n – 1 \) を満たす \( a_i \) を変えるとき、\( a_{i-1} \) または \( a_{i + 1} \) に変えることが考えられますが、どちらに変えたとしても、必要な操作回数は、
\[b – (|a_{i} – a_{i+1}| + |a_{i+1} – a_{i}|) + |a_{i + 1} – a_{i – 1}|\]
となります。したがって、全探索によって答えを求めます。
コード
#include <bits/stdc++.h> using namespace std; typedef long long ll; template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; } int n; ll a[200000]{}; void solve() { ll cnt = 0; ll c = max(abs(a[1] - a[0]), abs(a[n - 1] - a[n - 2])); for (int i = 1; i < n - 1; i++) { chmax(c, abs(a[i] - a[i - 1]) + abs(a[i + 1] - a[i]) - abs(a[i + 1] - a[i - 1])); } for (int i = 1; i < n; i++) { cnt += abs(a[i - 1] - a[i]); } cout << cnt - c<< "\n"; } int main() { int t; cin >> t; for (int i = 0; i < t; i++) { cin >> n; for (int j = 0; j < n; j++) { cin >> a[j]; } solve(); } return 0; }
ディスカッション
コメント一覧
まだ、コメントがありません