E - Simultaneous Kagamimochi 解説 by en_translator
We introduce two approaches with the worst time complexity \(\Theta(N)\).
Partition the sequence into two: the first \(\left\lfloor\dfrac N2\right\rfloor\) items and the others.
We will design an algorithm where we scan the latter part from the front, and pair each of them with the smallest remaining mochi that can be paired if possible.
The sought maximum value can be always achieved by this algorithm. Justification: if \(K\) pairs can be made, we can do so with the first \(K\) mochi’s, and \(K\) among the \(\left\lceil\dfrac N2\right\rceil\) mochi’s in the latter half. Moreover, at the point when the first \(k\) mochi’s have been paired with others, this algorithm gives an optimal set of the remaining mochi’s in the latter half.
The following is sample code.
#include <iostream>
#include <deque>
int main() {
using namespace std;
unsigned N;
cin >> N;
// The first `floor(N / 2)` of the mochi sequence
deque<unsigned> A(N / 2);
for (auto&& a : A)
cin >> a;
unsigned ans{};
for (unsigned i{N / 2}; i < N; ++i) {
unsigned a;
cin >> a;
// If it can be paired with the smallest remaining mochi, pair it
if (A.front() * 2 <= a) {
++ans;
A.pop_front();
}
}
cout << ans << endl;
return 0;
}
For convenience, we assume that there are an infinite number of mochi’s of an infinite size after the sequence. Here, we will consider the minimum possible maximum index of a mochi for the bottom when to the first \(K\) mochi’s are all paired as a top mochi. (In other words, we consider how many first mochi’s are required when making \(K\) pairs.)
One can find \(B _ i\coloneqq\) the smallest index \((1\leq i\leq N)\) eligible for the bottom mochi when using the \(i\)-th mochi as the top, in \(\Theta(N)\) time (with the sliding window technique just as Problem C). Then, we can represent this value as \(\displaystyle K+\max\left\lbrace\max _ {1\leq i\leq K}\lbrace B _ i-i\rbrace,K\right\rbrace\) using \(B_i\).
All that left is to find the maximum \(K\) where this value is not greater than \(N\). This can be found by computing \(B _ i\) while scanning \(K\) in ascending order.
The following is sample code. (Note that the code adopts 0-based indexing, while the explanation adopted 1-based.)
#include <iostream>
#include <vector>
int main() {
using namespace std;
unsigned N;
cin >> N;
vector<unsigned> A(N);
for (auto&& a : A)
cin >> a;
for (unsigned i = 0, j = 0, d = 0; i < N; ++i) {
// j := the index of the smallest mochi which we can place mochi i on
while (j < N && A[i] * 2 > A[j]) ++j;
// d := maximum difference of the indices of the two mochis in a pair
d = max(d, j - i);
// If the latter sticks out,
if (i + max(d, i + 1) >= N) {
// then the previous value is the answer.
cout << i << endl;
return 0;
}
}
return 0;
}
投稿日時:
最終更新: