LintCode 394. Coins in a Line (博弈类DP 经典题)

本文探讨了一种两人轮流从一排硬币中取走一枚或两枚的游戏策略。通过分析,揭示了游戏胜负的关键在于硬币总数是否为3的倍数。文章提供了两种解法,一种是基于数学逻辑的简洁判断,另一种是使用动态规划的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. Coins in a Line

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 player will win or lose?

If the first player wins, return true, otherwise return false.

Example
Example 1:

Input: 1
Output: true
Example 2:

Input: 4
Output: true
Explanation:
The first player takes 1 coin at first. Then there are 3 coins left.
Whether the second player takes 1 coin or two, then the first player can take all coin(s) left.
Challenge
O(n) time and O(1) memory

解法1:
经过分析可知,当n为3的倍数时,先手肯定输,否则先手肯定赢。
为什么呢?当n为3的倍数时,先手不管怎么取(取1个还是2个),后手都有办法让剩下的coin为3的倍数。最后当轮到先手时,剩下的coin为3,先手肯定输了。
当n不为3的倍数时,先手可以通过取1个或2个让剩下的coin为3的倍数。这样后手肯定输。比如说n=5,先手取2个,剩下3个,后手肯定输。

代码如下:

class Solution {
public:
    /**
     * @param n: An integer
     * @return: A boolean which equals to true if the first player will win
     */
    bool firstWillWin(int n) {
        return n % 3;
    }
};

解法2:
用DP。参考
http://www.cnblogs.com/grandyang/p/5861500.html
代码如下:

class Solution {
public:
    /**
     * @param n: an integer
     * @return: a boolean which equals to true if the first player will win
     */
     bool firstWillWin(int n) {
        if (n <= 0) return false;
        if (n <= 2) return true;
        vector<bool> dp(n + 1, true);
        dp[3] = false;
        for (int i = 4; i <= n; ++i) {
            dp[i] = dp[i - 3];
        }
        return dp.back();
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值