CF1763C Another Array Problem
题目大意:
有一个数列 \(a\),每次操作可以选择两个位置 \(i,j(1 \le i < j \le n)\),然后把所有位置 \(k(i \le k \le j)\) 的值 \(a_k\) 变成 \(|a_i - a_j|\)。
问若干次操作后,序列的和的最大值为多少?
思路:
序列的和的最大值可以在所有数都等于原序列中的最大值时取到。下令位置 \(x\) 为最大值。
操作一:可以先让区间 \([1,2]\) 进行两次操作使 \(a_1,a_2\) 都变为 \(0\),然后对区间 \([1,x]\) 进行操作;
操作二:然后再让区间 \([n - 1,n]\) 进行两次操作使 \(a_{n - 1},a_n\) 都变为 \(0\),然后对区间 \([1,n]\) 进行操作。
\(\texttt{Tips : }\)当 \(1 \le x \le 2\) 时,先对做操作二。
上为 \(3 < n\) 是的情况,下为特殊情况 \((n \le 3)\):
- \(\texttt{if n==1}\)
无法操作,输出 \(a_1\)。 - \(\texttt{if n==2}\)
要么操作 \([1,2]\),要么不操作,输出 \(\max(a_1 + a_2, 2 \times |a_1 - a_2|)\)。 - \(\texttt{if n==3}\)
- 不操作:\(a_1 + a_2 + a_3\)。
- 最大值位置不为 \(2\):仍然可以使所有数变为最大值,输出 \(3 \times Maxl\)。
- 最大值位置为 \(2\):
- 先操作 \([1,2]\),可以使所有值变为 \(\max(a_2 - a_1, a_3)\),输出 \(3 \times \max(a_2 - a_1, a_3)\)。
- 先操作 \([2,3]\),可以使所有值变为 \(\max(a_2 - a_3, a_1)\),输出 \(3 \times \max(a_2 - a_3, a_1)\)。
代码:
#include <bits/stdc++.h>
#define ll long long
#define Maxn 200005
using namespace std;
ll T, n, a[Maxn], maxl, x;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> T;
while (T --) {
cin >> n, maxl = x = -1;
for (ll i = 1; i <= n; i ++) {
cin >> a[i], x = (maxl < a[i] ? i : x);
maxl = max(maxl, a[i]);
}
if (n == 1) {
cout << a[1] << "\n";
} else if (n == 2) {
cout << max(a[1] + a[2], 2 * (max(a[1], a[2]) - min(a[1], a[2]))) << "\n";
} else if (n == 3) {
if (x != 2) { cout << n * maxl << "\n"; }
else { cout << max({a[1] + a[2] + a[3], 3 * max(a[2] - a[1], a[3]), 3 * max(a[2] - a[3], a[1])}) << "\n"; }
} else {
cout << n * maxl << "\n";
}
} return 0;
}
标签:le,maxl,max,最大值,texttt,Another,操作,Array,Problem
From: https://www.cnblogs.com/BLM-dolphin/p/18565461