博弈论

我们通常会遇到关于博弈论类似的题目,本文总结了刷题过程中该类型的题目。

1. leetcode 292.NIM游戏

题目描述:你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。

你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。

解题思路:由于每次A和B每个人最多能拿3块石头,那么只要满足一个条件即可获胜:A拿了1-3块石头中,只要有一种情况下B都使无法获胜,那么A一定会获胜。

按照常规解题思路,采用动态规划求解:
1.状态定义:dp[i]定义为一共有i块石头,当前拿石头的人能否获胜
2.状态转移方程:dp[i] = !(dp[i-1]&&dp[i-2]&&dp[i-3])
状态方程的含义:

  • dp[i-1]表示A拿了1块石头,B能否获胜;
  • dp[i-2]表示A拿了2块石头,B能否获胜;
  • dp[i-3]表示A拿了3块石头,B能否获胜;
  • 只要dp[i-1],dp[i-2],dp[i-3]这三种情况,只要有一种情况能让B无法获胜,那么一定是A获胜。
  • 所以就有dp[i] = !(dp[i-1]&&dp[i-2]&&dp[i-3])

代码

    public static boolean canWinNim(int n) {
     
    	boolean[] dp = new boolean[n+1];
 	    if(n<4)
            return true;
        dp[0] = false;
        dp[1] = true;
        dp[2] = true;
        dp[3] = true;
    	for (int i = 4; i < dp.length; i++) {
     
			dp[i] = !(dp[i-1]&&dp[i-2]&&dp[i-3]);
		}
    	return dp[n];     
    }

通过动态规划发现,内存超出限制。
并且n为4的倍数时,返回的一定是false,不是4的倍数的时候返回一定是true。所以直接让n对4取余即可得到答案, 有种脑筋急转弯的感觉。。。

但是个人觉得,为了应对变化的题型,对于博弈论类型的题目,还是得掌握动态规划的解题思路。

你可能感兴趣的:(算法刷题)