j今天刷的题是LeetCode292题,题目的要求是:桌子有一堆石头,每次你和你的朋友可以拿1~3块,拿掉最后一块石头的人胜利,你作为先手,判断在给定石头数量的情况下,是否可以赢得比赛。
分析:
这个题是巴什博奕
* 当石子有1−m个时,毫无疑问,先手必胜
* 当石子有m+1个时,先手无论拿几个,后手都可以拿干净,先手必败
* 当石子有m+2−2m时,先手可以拿走几个,剩下m+1个,先手必胜
* 我们不难发现,面临m+1个石子的人一定失败。
* 这样的话两个人的最优策略一定是通过拿走石子,使得对方拿石子时还有m+1个
* 我们考虑往一般情况推广 :设当前的石子数为n=k∗(m+1)+r
* 先手会首先拿走r个,接下来假设后手拿走x个,先手会拿走m+1−x个,这样博弈下去后手最终一定失败
* 设当前的石子数为n=k∗(m+1)
* 假设先手拿x个,后手一定会拿m+1−x个,这样下去先手一定失败
当我们明白了以上分析之后,代码就很好写了,如下:
public class canWinNim_292_simple { public static boolean solution(int n){ int num=n%4; if (num==0)return false; else return true; } }