[ABC354E] Remove Pairs 博弈论 + 状压dp
作者:
多米尼克領主的致意
,
2024-05-19 19:22:55
,
所有人可见
,
阅读 3
因为N的大小为18容易想到状压dp
状态定义:定义f为当前的状态是必胜态或是必败态 初始化为0(必败态)
思路:
1.根据集合18种状态给出集合S的上限为(1 << 18) - 1 下限为S = 0
2.枚举拿走的两张卡片i,j
3.写出状态转移方程f[s] |= (!f[(s^(1 << i)^(1 << j)])
表示s - 2^i - 2^j的集合中 只要存在必败态 那么当前就可以是必胜态
4.特判 i == j 以及 i j在s中存在(为1)
5.判断最终状态f[(1 << n) - 1]的胜负手
code:
#include <bits/stdc++.h>
using namespace std;
int n, f[1 << 18];
int a[20], b[20];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
for(int i = 0;i < n;i++){
cin >> a[i] >> b[i];
}
// f[0] = 1;
for(int s = 0; s <= (1 << n) - 1;s++){
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
if(i == j)continue;
if(a[i] == a[j] || b[i] == b[j]){
if(((s >> j) & 1) && ((s >> i) & 1))
f[s] |= (!f[s^(1 << i)^(1 << j)]);
}
}
}
}
if(f[(1 << n) - 1])cout << "Takahashi";
else cout << "Aoki";
return 0;
}