まず、 と が定まっているとき、 以上で 以下の要素は選んだ方が得であるということが分かります。なぜなら、負の項に変化なくプラスの項 を大きくできるからです。
を固定して考えます。( を固定しても結果は同じですが、今回は最小値を固定する方針で考えます。)
まず、配列 を昇順にします。
区間の左端のインデックス を小さいほうから見ていき、 番目から何番目までの要素を選べばよいかを知りたいです。
仮に右端のインデックスを として、 と の差分を見てみます。
そうすると、右端をひとつ進めるごとに、 の値は大きくなりますが、 の増加分がそれを上回るため、右端を進めた方が得であるとわかります。
よって、各 番目から 番目を選んだ時のスコアのうち、最大値が答えとなります。
区間和を累積和を用いて求めることで全体の計算量は となります。
xxxxxxxxxx
using namespace std;
using ll = long long;
int main() {
ll N;
cin >> N;
vector<ll> A(N);
for (ll i = 0; i < N; i++) {
cin >> A[i];
}
sort(A.begin(), A.end());
vector<ll> sum(N + 1, 0);
for (ll i = 0; i < N; i++) {
sum[i + 1] = sum[i] + A[i];
}
ll ans = 0;
for (ll i = 0; i < N; i++) {
ans = max(ans, (sum[N] - sum[i]) - abs(A[N - 1] - A[i]));
}
cout << ans << endl;
}
xxxxxxxxxx
n = int(input())
A = list(map(int,input().split()))
A.sort()
CA = [0]
for i in range(n):
CA.append(CA[-1] + A[i])
s = CA[-1]
ans = 0
for i in range(n):
ans = max(ans, s - CA[i] -(A[-1] - A[i]))
print(ans)