Stick lengths
Abridged problem statement
You are given an array of length . Choose an array such that for all , and is minimized.
Solution
Let’s fix the final value each ends up with: call this . Then, our goal is to choose an that minimizes .
Here’s a plot of the value of against for :
We can make some inferences from this graph. To begin with, it looks like the graph decreases first, then becomes flat, and then increases. In addition to this, the minimum value seems to be attained at all values from to .
Let us try generalising these observations. Define , and examine the value of :
- Changing to brings us closer to all .
- It also brings us farther from all .
That is,
So, define , then . Therefore, when . Since is an integer, this becomes .
In other words, as long as there are less than elements to our left, is better than . After that, is worse (or just as good as) . So we pick such that there are exactly elements to the left of it in our array.
Such a value is called a median of the array. Hence, the minimum is attained when is a median of . If is even, every value between the two medians is optimal.
Code
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
int main() {
int n;
cin >> n;
vector<int> a(n);
for (int &i : a) {
cin >> i;
}
sort(a.begin(), a.end());
int64 ans = 0;
for (int &i : a) {
ans += abs(a[(n - 1) / 2] - i);
}
cout << ans << '\n';
}