H - Remove Pairs Editorial by en_translator
There are \(2^{N}\) possible sets of cards on the table. It is sufficient to determine for each of them whether the first or second player will win if these cards is on the table right before the first player makes a move.
This can be solved with the technique so-called bit DP.
Let \(dp[S]\) = true
if the first player will win if the cards in \(S\) are on the table right before the first player makes a move, and false
otherwise.
The transitions are as follows.
For a set \(S\) of cards, if \(dp[S \setminus \{i,j\}]\) is
false
for some pair \(i,j \in S\) such that \(A_i=A_j\) or \(B_i=B_j\), then \(dp[S]\) istrue
; otherwise, it isfalse
.
The final answer is Takahashi
if \(dp[S]\) for \(S=\{1,2,\ldots,N\}\) is true
and Aoki
otherwise.
The number of states is \(O(2^{N})\) and each transition costs \(O(N^{2})\) time, so the total complexity is \(O(2^{N} {N}^{2})\), which is fast enough.
Sample code (C++):
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> a(n), b(n);
for (int i = 0; i < n; ++i)
cin >> a[i] >> b[i];
vector<int> dp(1 << n, -1);
dp[0] = 0;
for (int i = 1; i < (1 << n); ++i) {
bool f = false;
for (int j = 0; j < n; ++j)
for (int k = j + 1; k < n; ++k) {
if (((i >> j) & 1) && ((i >> k) & 1)) {
if ((a[j] == a[k] || b[j] == b[k]) && dp[i ^ (1 << j) ^ (1 << k)] == 0) {
f = true;
}
}
}
dp[i] = f;
}
cout << (dp.back() ? "Takahashi" : "Aoki") << endl;
}
posted:
last update: