292. Nim Game

来源:互联网 发布:国际航协2015数据 编辑:程序博客网 时间:2024/06/08 13:52

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.

方法一: recursive

class Solution {public:    bool canWinNim(int n) {        if (n <= 0) {            return false;        }        if (n <= 3) {            return true;        }        bool q[3];        for (int i = 0; i < 3; i++) {            q[i] = true;            for (int j = 0; j < 3; j++) {                q[i] = q[i] && canWinNim(n - i - 1 - j - 1);            }        }        return q[0] || q[1] || q[2];    }};

后来发现,并不需要限定到都是我先开始抽,因为谁先开始抽对应的结论是一样的,对于我,只需要把对手先抽的结论反过来就行。
改进代码:

class Solution {public:    bool canWinNim(int n) {        if ((n == 1) || (n == 2) || (n ==3)) {            return true;        }        if (canWinNim(n - 1) && canWinNim(n - 2) && canWinNim(n - 3)) {            return false;        } else {            return true;        }    }};

递归最大的问题就是会在一些common subproblems 做repeated computing。这就是dp的意义。

方法二: dynamic programming
bottom-up manner

class Solution {public:    bool canWinNim(int n) {        bool dp[n + 1];        int i;        for (i = 0; i <= n; i++) {            dp[i] = true;        }        dp[0] = false;        if (n <= 3) {            return dp[n];        }        for (i = 4; i <= n; i++) {            dp[i] = ! (dp[i - 1] && dp[i - 2] && dp[i - 3]);        }        return dp[n];    }};

但是这个也没法通过leetcode的测试,recursive是在前面就死在时间上,dp是死在空间上了,直接报runtime error,我看了看错的例子,给了个是13亿,内存直接爆掉了。

方法三:only solution 找规律
可以发现只要是4的倍数,就一定输,不是就不输,所以,哦。。。

class Solution {public:          bool canWinNim(int n) {        return n % 4 != 0;    }};
原创粉丝点击