一直在用考的少的理由,不学博弈论(game)。不学还是不行啊,先学个sg记忆化状态
1.sg()函数是递归求解某个状态sg值的过程,fg[]用来记忆化。
2.每个sg函数可以理解为一张有向无环图,每次遍历他的出边
3.求出每个堆的sg值后,再用尼姆博弈基本定理。
int s[105], fg[10010];
int n, m;
int sg(int x)
{
if (fg[x] != -1)return fg[x];//搜到过,记忆化就是棒
unordered_set<int> st;
f(i, 1, m)//拓展他的可能出边
{
int now = s[i];
if (x >= now)st.insert(sg(x - now));//递归并维护一个MEX数组
}
for (int i = 0;;++i)
if (!st.count(i))
return fg[x] = i;//找到mex,记忆化,并返回
}
int main()//sg函数实质是记忆化搜索,f[N]存每种状态的值,对每个sg求拓展它能到达的状态,然后对每张图进行尼姆博弈
{
cin >> m;
f(i, 1, m)cin >> s[i];//可能状态转移价值
cin >> n;
int x;
int ans = 0;
memset(fg, -1, sizeof fg);//记忆化数组
f(i, 1, n)
{
cin >> x;
ans ^= sg(x);
}
if (ans == 0)puts("No");
else puts("Yes");
return 0;
}