E - Remove Pairs(狀壓dp+博弈論)

临江柔發表於2024-05-22

思路:

容易發現,我們取走一張牌後:

如果下一步的人必敗,則這一步的人必勝,因為可以走這個狀態。反之,這個人必敗。

程式碼:

#include <bits/stdc++.h>
using namespace std;
int n, a[21], b[21], f[2000005];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i] >> b[i];
    for (int S = 0; S <= ((1 << n) - 1); S++)//狀壓dp
        for (int i = 1; i <= n; i++)
            for (int j = i + 1; j <= n; j++)
                if (!(S & (1 << i - 1)))
                    if (!(S & (1 << j - 1)))//兩張牌都沒選才能 dp
                        if (a[i] == a[j] || b[i] == b[j])
                            if (!f[S])   //如果當前狀態的上一個狀態為先手必敗,那麼可以轉移,因為上次必敗,那麼這次先手必勝。
                                f[S | (1 << i - 1) | (1 << j - 1)]++;
    if (!f[(1 << n) - 1])//判斷是否先手必勝
        cout << "Aoki";
    else
        cout << "Takahashi";
}

相關文章