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

动态规划:博弈型

博弈型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];
    }
发布了43 篇原创文章 · 获赞 6 · 访问量 3907

猜你喜欢

转载自blog.csdn.net/weixin_44424668/article/details/104017362
今日推荐