#394 Coins in a Line

来源:互联网 发布:linux使用ftp传输文件 编辑:程序博客网 时间:2024/05/21 19:31

题目描述:

There are n coins in a line. Two players take turns to take one or two coins from right side until there are no more coins left. The player who take the last coin wins.

Could you please decide the first play will win or lose?

Example

n = 1, return true.

n = 2, return true.

n = 3, return false.

n = 4, return true.

n = 5, return true.

Challenge 

O(n) time and O(1) memory

题目思路:

这题属于博弈类dp题,win的精髓在于不能把宝压在对手上,也就是说,无论对手采取什么选择,都会win。用dp[i]表示有i个coin时,自己会不会win。那么想到,走到i有两种可能:自己拿了2个coins或者拿了1个coin走到的i。那我们要保证自己拿了2个coin必win,或者自己拿了1个coin必win(因为自己拿多少是可以选的)。也就是说,自己拿2个coin时,必须保证dp[i-4](对手拿2), dp[i-3](对手拿1)都是true的;自己拿一个coin时,必须保证dp[i-2](对手拿1), dp[i-3](对手拿2)都是true的。

搞清了逻辑之后,code倒是 

Mycode(AC = 12ms):

class Solution {public:    /**     * @param n: an integer     * @return: a boolean which equals to true if the first player will win     */     bool firstWillWin(int n) {        // write your code here        if (n == 0 || n == 3) {            return false;        }        if (n == 1 || n == 2) {            return true;        }        else {            vector<bool> dp(n + 1, false);            dp[1] = true;            dp[2] = true;            dp[3] = false;                        // ensure whether player 2 pick            // 1 or 2 coins, player 1 will win            for (int i = 4; i <= n; i++) {                dp[i] = (dp[i - 3] && dp[i - 2]) || // player1 pick 1 coin                        (dp[i - 4] && dp[i - 3]); // player1 pick 2 coins            }                        return dp[n];        }    }};


0 0