动态规划解题模版:博弈型

本文深入探讨了博弈型动态规划的策略,通过分析LintCode394CoinsinaLine问题,阐述了如何判定先手玩家在特定游戏规则下是否必胜。文章详细解释了状态转移方程,展示了递推过程,并提供了简洁的Java实现代码。
摘要由CSDN通过智能技术生成

动态规划:博弈型

博弈型dp一般从第一步分析,而不是最后一步,需要开n+1

1、LintCode 394 Coins in a Line

【问题】有 n 个硬币排成一条线。两个参赛者轮流从右边依次拿走 1 或 2 个硬币,直到没有硬币为止。拿到最后一枚硬币的人获胜。请判定 先手玩家必胜还是必败?

【分析】从第一步开始,一开始有n个硬币,A可以拿一个或两个硬币,这样B则对应拿n-1个或n-2个硬币,A肯定会采取策略让自己获胜。然后不断拿。假设一开始有5个硬币,可以画出如果所示的树形结构,必败就是自己无路可逃,必胜就是有赢的可能。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3HH8MNpW-1575735100624)(/Users/zhangye/Library/Application Support/typora-user-images/image-20191207201606034.png)]

【状态】设dp[i]表示面对i个硬币,是否先手必胜则有下面几种情况

  • dp[i] = true,f[i-1]==false || f[i-2]==false(对手拿1个或2个都是必败的情况)
  • dp[i] = false,f[i-1]==true && f[i-2]==true(对手拿1个或2个都是必胜的情况)

【初始情况与边界】

  • dp[0] = 0,面对0个硬币,必败
  • dp[1] = dp[2] = true
public boolean firstWillWin(int n) {
        if (n == 0) {
            return false;
        }
        if (n <= 2) {
            return true;
        }
        boolean[] dp = new boolean[n + 1];
        dp[0] = false;
        dp[1] = true;
        for (int i = 2; i <= n; i++) {
            // if (dp[i - 1] == true && dp[i - 2] == true) {
            //     dp[i] = false;
            // } else {
            //     dp[i] = true;
            // }
            dp[i] = !dp[i - 1] || !dp[i - 2];
        }
        return dp[n];
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值