leetcode刷题16

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;
    }
}
原文地址:https://www.cnblogs.com/cquer-xjtuer-lys/p/11411622.html