我们通常会遇到关于博弈论类似的题目,本文总结了刷题过程中该类型的题目。
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取余即可得到答案, 有种脑筋急转弯的感觉。。。
但是个人觉得,为了应对变化的题型,对于博弈论类型的题目,还是得掌握动态规划的解题思路。
598

被折叠的 条评论
为什么被折叠?



