题目:
You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones.
Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap.
For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend.
Hint:
- If there are 5 stones in the heap, could you figure out a way to remove the stones such that you will always be the winner?
就是现在又一堆石头,每个人每次只能取1个,2个或者是3个石头,你先开始取,然后是你的对手取,然后依次轮流,最后一个将石头取完的人获胜。那么给定一个有n个石头,判断先手能否取胜。
题解:
这是一道在经济学中非常重要的关于博弈论的题目,专门有一讲是关于Nim Game的,也可以把这个问题归为Bash Game(巴什博奕)巴什博弈:只有一堆n个物品,两个人轮流从这堆物品中取物, 规定每次至少取一个,最多取m个,最后取光者得胜。解答如下:
显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。因此我们发现了如何取胜的法则:如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。总之,要保持给对手留下(m+1)的倍数,就能最后获胜。所以,如果碰到这个n 为m+1的倍数,那么先手那人肯定输,否则就是后手输。
这题的m为3,那么只要没有碰到m+1=4的倍数,那么先手就必赢,否则就是输。
public class Solution
{
public boolean canWinNim(int n)
{
if(n % 4 == 0)
return false;
else
return true;
}
}
代码非常简单,但是蕴含的数学知识——博弈论,却非常精彩。关于Nim Game,在《编程之美》中专门有讲到。