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.
A valid final pair is not two independent strings. Once you choose the true , the true is forced by prefix parity.
Flip the dependency around: if you know the true parity string , then each original bit is determined by two neighboring parity values: , where .
So the task becomes: choose a binary string minimizing That is just a shortest path through two possible states per position. Tiny DP, no black magic.
Let be the minimum cost after processing positions if the true parity bit . Transition from previous bit to current bit and pay for both recorded strings at position .
Initialize from . For every position, try all : The answer is after the last position.
The clean way to look at this problem is to stop treating and like two freely chosen strings. They are glued together by prefix parity.
For a valid pair, is the parity of the number of ones in . So when we move from position to position , the parity changes exactly when .
That gives the important relation:
with a fake starting value
because before reading any bits, the count of ones is , which is even.
So if we choose the true parity string , the true test string is completely forced. No need to guess both. Guessing both would be doing extra cardio for no reason.
Reformulating the cost
We are given recorded strings and . We need the closest valid pair .
Using the relation above, choosing gives:
At position , the cost is:
So the total cost is:
Now each position only depends on the previous parity bit. That screams two-state DP.
DP definition
Let:
be the minimum cost after processing the current prefix, assuming the last chosen parity bit is .
Initially, before processing anything, the previous parity is fixed as , so:
For each position , we choose the current parity bit and transition from the previous parity bit .
The extra cost is:
because:
Transition:
After all positions, the last parity can be either or , so the answer is:
Why this is correct
Every valid pair corresponds to exactly one choice of , because .
Every binary string also creates exactly one valid using that same formula. So we are optimizing over all valid pairs without missing any and without counting invalid nonsense.
The DP checks all possible parity strings implicitly. Since the cost at position depends only on and , keeping the best cost for each possible last parity bit is enough. Classic shortest-path-on-a-line stuff. Very chill.
Complexity
There are positions and only transitions per position.
Time complexity per test case:
Memory complexity:
The total input length is at most , so this comfortably fits. The computer will not even break a sweat.
#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--) {
string xp, yp;
cin >> xp >> yp;
const int INF = 1e9;
int dp[2] = {0, INF}; // before position 1, y_0 = 0
for (int i = 0; i < (int)xp.size(); i++) {
int xbit = xp[i] - '0';
int ybit = yp[i] - '0';
int ndp[2] = {INF, INF};
for (int prev = 0; prev < 2; prev++) {
for (int cur = 0; cur < 2; cur++) {
int forcedX = prev ^ cur;
int cost = (cur != ybit) + (forcedX != xbit);
ndp[cur] = min(ndp[cur], dp[prev] + cost);
}
}
dp[0] = ndp[0];
dp[1] = ndp[1];
}
cout << min(dp[0], dp[1]) << '\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--) {
string xp, yp;
cin >> xp >> yp;
const int INF = 1e9;
int dp[2] = {0, INF}; // before position 1, y_0 = 0
for (int i = 0; i < (int)xp.size(); i++) {
int xbit = xp[i] - '0';
int ybit = yp[i] - '0';
int ndp[2] = {INF, INF};
for (int prev = 0; prev < 2; prev++) {
for (int cur = 0; cur < 2; cur++) {
int forcedX = prev ^ cur;
int cost = (cur != ybit) + (forcedX != xbit);
ndp[cur] = min(ndp[cur], dp[prev] + cost);
}
}
dp[0] = ndp[0];
dp[1] = ndp[1];
}
cout << min(dp[0], dp[1]) << '\n';
}
return 0;
}