Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
After the operation, becomes . That means every prefix minimum from position onward becomes too. So only the prefix before still matters.
The annoying part is . Since , this can only make earlier prefix minimums worse, never better.
If there is already some earlier element , then increasing changes nothing about any prefix minimum. In other words, index is “safe” when .
For a safe index , use the operation on . Then all prefix minimums after become , and the cost is just the original sum of prefix minimums up to .
If no usable safe index has appeared yet, the best risky move is just zeroing position : choose , giving cost . So the answer is the minimum of the original value, , and the prefix-minimum sum up to the first safe index before .
Let
The value we care about is
The operation chooses , does , then sets .
The second part is huge: once , every prefix containing position has minimum . So after the operation, all terms from onward contribute nothing. Nice.
The only possible downside is that got increased, so some prefix minimums before might become larger. Since all values are nonnegative, , so this increase can never help. It either does nothing or makes things worse.
When is an index safe?
Suppose we choose some index . Let
If , then was not responsible for lowering the prefix minimum. There is already an earlier element at most as small as it.
So increasing changes nothing for prefix minimums at positions before the zero. The earlier smaller element still wins.
So index is safe exactly when
If such a safe index exists, we should choose . Why wait longer? Choosing makes everything after become as early as possible, and increasing does not hurt. The resulting value is simply
Since prefix minimums are nonnegative, these prefix sums never decrease, so the earliest safe usable index gives the best such move.
What if we use an unsafe index?
Unsafe means is strictly smaller than everything before it. It is a new prefix minimum.
If you increase such an element, you may destroy the very reason it was useful. That is bad. We need to show we do not need to try every unsafe operation.
There is always the simple operation . It gives value
because position becomes , so everything after it contributes .
Now consider any unsafe choice before the first safe index. The array has been strictly decreasing so far, so just the first two prefix-minimum terms already sum to . Delaying the zero cannot beat that; it only keeps more nonnegative terms alive.
So the only candidates are:
We scan left to right while maintaining the current prefix minimum and prefix-minimum sum. Whenever is at least the previous prefix minimum and , index is safe, so we minimize the answer with the prefix sum through .
That is per test case, with total .
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<ll> a(n);
for (ll &x : a) cin >> x;
ll mn = a[0], original = 0;
for (int i = 0; i < n; i++) {
mn = min(mn, a[i]);
original += mn;
}
ll ans = min(original, a[0] + a[1]);
mn = a[0];
ll prefSum = a[0];
for (int i = 1; i < n - 1; i++) {
if (a[i] >= mn) {
ans = min(ans, prefSum + mn);
}
mn = min(mn, a[i]);
prefSum += mn;
}
cout << ans << '\n';
}
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<ll> a(n);
for (ll &x : a) cin >> x;
ll mn = a[0], original = 0;
for (int i = 0; i < n; i++) {
mn = min(mn, a[i]);
original += mn;
}
ll ans = min(original, a[0] + a[1]);
mn = a[0];
ll prefSum = a[0];
for (int i = 1; i < n - 1; i++) {
if (a[i] >= mn) {
ans = min(ans, prefSum + mn);
}
mn = min(mn, a[i]);
prefSum += mn;
}
cout << ans << '\n';
}
}