Ferris wheel
Abridged problem statement
Given an array and an integer , partition the elements of into as few groups as possible. Each group may contain at most two elements, and the sum of its elements must not exceed . Determine the minimum number of groups.
Solution
Note: we use the same technique introduced in this article, which may be considered a prerequisite.
Once again, let us employ the extremal principle. Given , assuming , consider and .
If , we are forced to create a separate group for —it cannot pair with any other element if it can’t pair with the smallest!
If , must we pair with ?
Consider the contrary—that is—consider the case when is paired with some other element . We have two subcases:
Case #1: is unpaired
(symmetric to is unpaired, which has been omitted)
In this case, we can simply replace with , keeping the number of groups the same.
Case #2: is paired with some other
We know that (turns out we don’t even need to use ).
Since and , as well. But is ?
Yes, because and implies .
So, yes, pairing with really just works. This may seem somewhat magical at first, but we’re actually doing almost the exact same thing as in apartments.
Implementation
We maintain a pointer at the front and back.
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, x;
cin >> n >> x;
vector<int> a(n);
for (int &i : a) {
cin >> i;
}
sort(a.begin(), a.end());
int i = 0, j = a.size() - 1;
int ans = 0;
while (i <= j) {
ans++;
if (a[i] + a[j] <= x) {
i++, j--;
} else {
j--;
}
}
cout << ans << '\n';
}