动态规划 1025除数博弈

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,然后爱丽丝无法进行操作。

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

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

法二:动态规划
d p [ i ] dp[i] dp[i]来表示当初始值是 i i i时爱丽丝的输赢情况。 d p [ 0 ] = 0 ; d p [ 1 ] = 0 ; d p [ 2 ] = 1 ; dp[0] = 0; dp[1]=0;dp[2]=1; dp[0]=0;dp[1]=0;dp[2]=1;
d p [ i ] dp[i] dp[i]的判断和前面有关系,当 i i i前面的 j ∈ [ 1 , i − 1 ] j\in[1,i-1] j[1,i1]中有i%j==0并且dp[i-j]==0(因为下一步鲍勃得到的值是 i − j i-j ij, d p [ i − j ] = 0 dp[i-j]=0 dp[ij]=0说明鲍勃是输的) 则 d p [ i ] = 1 dp[i]=1 dp[i]=1,否则 d p [ i ] = 0 dp[i]=0 dp[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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值