动态规划 1025除数博弈

本文介绍了一个名为“除数博弈”的游戏,该游戏由两名玩家爱丽丝和鲍勃轮流进行。通过两种方法探讨了如何确定先手玩家爱丽丝能否获胜:一是利用奇偶性判断,二是采用动态规划的方法。

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

1025 除数博弈
爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。

最初,黑板上有一个数字 N。在每个玩家的回合,玩家需要执行以下操作:

选出任一 x,满足 0 < x < NN % x == 0
N - x 替换黑板上的数字 N
如果玩家无法执行这些操作,就会输掉游戏。

只有在爱丽丝在游戏中取得胜利时才返回True,否则返回 false。假设两个玩家都以最佳状态参与游戏。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/divisor-game

示例 1:
输入:2
输出:true
解释:爱丽丝选择 1,鲍勃无法进行操作。
示例 2:
输入:3
输出:false
解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。

力扣中已经有许许多多的题解了,相信很多也比我写的详细,在这里只是想自己把自己的思路记录下来,汇总到一起,以便日后复习巩固。
法一:
奇偶性判断
由于爱丽丝先手开局,当NNN为偶数时,爱丽丝选择x=1x = 1x=1,则鲍勃遇到的 为奇数,由于N%x==0N \% x == 0N%x==0中当NNN为奇数时,xxx必定为奇数,所以此时N−xN-xNx又为偶数。爱丽丝继续选择111,鲍勃得到的又是奇数。直到最后爱丽丝得到222,爱丽丝选择111,鲍勃无法操作。爱丽丝取胜。
NNN为奇数时,爱丽丝则变为了上面情况的鲍勃,最后一定失败。

class Solution {
public:
    bool divisorGame(int N) {
        if (N%2==0) return true;
        return false;
    }
};

法二:动态规划
dp[i]dp[i]dp[i]来表示当初始值是iii时爱丽丝的输赢情况。dp[0]=0;dp[1]=0;dp[2]=1;dp[0] = 0; dp[1]=0;dp[2]=1;dp[0]=0;dp[1]=0;dp[2]=1;
dp[i]dp[i]dp[i]的判断和前面有关系,当iii前面的j∈[1,i−1]j\in[1,i-1]j[1,i1]中有i%j==0并且dp[i-j]==0(因为下一步鲍勃得到的值是i−ji-jij,dp[i−j]=0dp[i-j]=0dp[ij]=0说明鲍勃是输的) 则dp[i]=1dp[i]=1dp[i]=1,否则dp[i]=0dp[i]=0dp[i]=0

class Solution {
public:
    bool divisorGame(int N) {
        if (N<=1) return false;
        vector<int> v(N+1);
        v[0]=0,v[1]=0,v[2]=1;
        for(int i = 3;i <= N; i++)
        {
            v[i]=0;
            for(int j=1;j<i;j++)
            {
                if (i%j==0&&v[i-j]==0)
                {
                    v[i]=1;break;//有一个使爱丽丝赢得情况即可
                }
            }
        }
        return v[N]==1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值