SG函数入门——【2017.5.28提高组模拟】Simple Game

来源:互联网 发布:java项目案例分析 编辑:程序博客网 时间:2024/06/08 19:00

Description:

这里写图片描述

Input:

这里写图片描述

Output:

Print the number of initial arrangements of piles that will result in Little Cat winning, modulo 10^9+7.

Sample Input:

4 3 3

Sample Output:

这里写图片描述

Data Constraint:

1<=M<=10
M<=N<=600
2<=k<=600

吹水:

又是英文题@¥!@

题目大意:

现在绝顶聪明两个人在玩一个游戏:有m个集合,总共有n个元素,两人轮流操作,每次选定一个元素个数大于1的集合,把它分成i(2 <= i <= k)个非空集合,每个集合的大小随便定,最后没得选的人判负。
要求建m个总共有n个东西的集合,且使得先手必赢,求方案数。
1 <= m <= 10, m <= n <= 600, 2 <= k <= n

题解:

博弈题。
利用sg函数,我们先求出单独一个集合是的sg值,然后动态规划拼一起就行了。

性质:
k = 2: sg(x) = 1 - x mod 2
k = 3: 暴力求。
k > 3: sg(x) = x - 1

证明:
最后一个不会,老曹说这种题的sg都要打表找规律。

这么讲肯定不懂sg的肯定还是懵。

先讲讲什么是sg。
x是一个状态,sg(x) 如果是0, 说明x这个状态先手必输,否则必赢。
sg有许多神奇的性质,实际上它的值很难解释意义。
1.x没有后继, sg(x) = 0
2.x有后继,a1,a2,a3..ak是它的后继,sg(x) = mex{sg(a1..k)}
3.x可以拆成一些互不影响的状态,如果它们分别是a1,a2..ak,sg(x) = sg(a1) xor sg(a2) xor sg(ak)

3证明现在我还不会,之后会补。

这道题中频繁用到3,好好理解就可了。