硬币游戏
一堆硬币,共n枚,两个人轮流从其中拿出若干枚,每次只能拿1个,2个或者4个。
规定最后一个拿硬币的人为输。问:在先手和后手中,谁有必胜策略?
比如,最简单的情况,总共就1枚硬币,则后手有必胜策略(而且无论如何必胜),
因为先手必须要拿走这一个。
如果总共2枚硬币,则先手有必胜策略,即,首先拿走一个,剩下一个,
则后手只能拿走最后一个,后手输。
利用三叉树解决这个问题。
用一颗三叉树代表一次游戏的所有可能过程,每一个节点代表一个当前的游戏状态。
每个节点有三颗子树,其中左孩子代表从当前的硬币堆中拿走1枚,中孩子代表拿走2个,
右孩子代表拿走三个。
每个节点除了存储三个子树(左中右)的指针外,还需要存储:
1. 当前剩余硬币枚数
2. 此节点的who_could_win属性,即对于此节点所对应的状态,先手有必胜策略还是后手有必胜策略,规定当剩余硬币数为0时,先手有必胜策略。根据以下两个原则,整棵树各个节点的who_could_win属性可以由底到根递归求得:
a) 若节点存在子树,且子节点的who_could_win属性均为“先手有必胜策略”,则此节点有后手必胜策略
b) 若节点不存在子树(剩余硬币为0),或者存在的子树中含有who_could_win属性为“后手有必胜策略”的,则此节点有先手必胜策略。
另外一种更简便的方式,
用f(n)代表 n个硬币时,谁能必胜 f(n)=先 或者f(n)=后
n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
f(n) | 后 | 先 | 先 | 后 | 先 | 先 | 后 | 先 | 先 |