今日算法之_157_Nim游戏
前言
Github:https://github.com/HealerJean
1、
你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。
你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。
示例:
输入: 4
输出: false
解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛;
因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。
1.1、解题思路
动态规划以及找规律
1.2、算法
1.2.1、算法1:动态规划
public boolean canWinNim2(int n) {
if (n == 1 || n == 2 || n == 3){
return true;
}
boolean[] dp = new boolean[n + 1];
dp[1] = true;
dp[2] = true;
dp[3] = true;
for (int i = 4; i <= n; i++) {
boolean flag = false;
for (int j = 1; j <= 3; j++) {
//只要有一个为false, 就表示有戏
if (!dp[i-j]){
flag = false;
break;
}
}
dp[i] =flag;
}
return dp[n];
}
1.2.2、算法1:找规律
/**
* 解法2,官方解法(有些像数三十,避免自己数到27)
* 避免自己最后就剩4 。所以不能选择4,只能选择1 2 3 , 5 6 7 ,看规律的话很明显,如果是4的倍数则false
*/
public boolean canWinNim(int n) {
if (n % 4 == 0) {
return false;
}
return true;
}
1.3、测试
@Test
public void test(){
for (int i = 0; i < 300; i++) {
System.out.println(canWinNim(20) == canWinNim2(20));
}
}