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.
Changing a position means its original value stops mattering completely. So think less about what you change, and more about which original values you decide to keep.
If you keep positions , their values must satisfy . Otherwise those two kept values would force a drop no matter what you do around them.
Any positions you do not keep can be filled with convenient numbers. If the kept values are nondecreasing, the changed values can always be chosen to fit between them. No weird integer gap issue exists because equality is allowed.
So minimizing changed cost is the same as maximizing the total cost of kept positions. You need a maximum-weight nondecreasing subsequence, where position has weight .
Use DP: let be the maximum saved cost of a valid kept subsequence ending at . Then over with , or just if nothing can come before it. Answer is .
The important move is to stop obsessing over the changed values. They can be any integers, so they are basically programmable filler.
We only need to decide which original positions stay unchanged.
Key Observation
Suppose we keep some positions:
Since these positions are not changed, their final values are still:
The final whole array must be nondecreasing, so these kept values also must be nondecreasing:
If you keep two positions with , you're cooked. No amount of changing the stuff between them can make the array nondecreasing, because the left fixed value is already bigger than the right fixed value.
So the kept positions must form a nondecreasing subsequence of the original array.
Is that condition enough?
Yes.
If the kept values are nondecreasing, every changed position can be assigned some value that fits. Between two kept values , set all changed positions there to or or anything in between if you feel fancy. Before the first kept value, use something no larger than it. After the last kept value, use something no smaller than it.
Because equality is allowed, there is no annoying “not enough integers between them” problem. This is not one of those cursed strict-increasing traps.
So:
Therefore the problem becomes:
Find a nondecreasing subsequence with maximum total cost .
Then subtract that saved cost from the total cost.
DP Definition
Let:
If we keep position , we save .
Before , we may append it after any position such that:
So:
If there is no such , then:
The best saved cost is:
The answer is:
For , this naturally gives answer , because we can keep the only element.
Complexity
The sum of over all test cases is at most , so the plain DP is completely fine:
In the worst case that is around million transitions, which is chill for 1 second in C++ if you don't write it like a sleep-deprived spreadsheet.
#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), c(n), dp(n);
for (ll &x : a) cin >> x;
ll total = 0;
for (ll &x : c) {
cin >> x;
total += x;
}
ll best = 0;
for (int i = 0; i < n; i++) {
dp[i] = c[i];
for (int j = 0; j < i; j++) {
if (a[j] <= a[i]) {
dp[i] = max(dp[i], dp[j] + c[i]);
}
}
best = max(best, dp[i]);
}
cout << total - best << '\n';
}
return 0;
}#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), c(n), dp(n);
for (ll &x : a) cin >> x;
ll total = 0;
for (ll &x : c) {
cin >> x;
total += x;
}
ll best = 0;
for (int i = 0; i < n; i++) {
dp[i] = c[i];
for (int j = 0; j < i; j++) {
if (a[j] <= a[i]) {
dp[i] = max(dp[i], dp[j] + c[i]);
}
}
best = max(best, dp[i]);
}
cout << total - best << '\n';
}
return 0;
}