【292】 Nim Game (2019年3月12日,E)

有一堆石头,游戏规则是每次可以从里面拿1-3颗石头,拿到最后的石头的人赢。你和你的对手都 optimal 的玩这个游戏,问先手(也就是你)能不能赢得这个比赛。

题解:我本来写的是 dfs + memo,但是没想到这个题数字太大了。容易爆栈。后来通过看discuss和观察,发现,这个题,只要不是 4 的倍数,先手都能赢得比赛。

1 class Solution {
2 public:
3     bool canWinNim(int n) {
4         return n % 4 != 0;
5     }
6 };

  

【375】Guess Number Higher or Lower II (2019年3月12日,google tag,H)

给了 1 ~ N 这 N 个数字猜数,我来猜,如果我猜错了,我猜这个数为x,那么我就付 x 元。返回在能保证我赢的情况下,返回我必须付多少钱。

 https://www.1point3acres.com/bbs/thread-197552-1-1.html

 

【464】Can I Win (2019年2月20日,谷歌tag,M)

给了一个1-100的游戏,游戏规则是,两个选手,player1每次从1-100中抽取一个数字,player2每次也从1-100中抽取一个数字,不能重复抽取相同的数字。直到某个player抽取到一个数,所有轮次中每个player抽取的数字加和大于等于target(target是提前给定的)。问player1能不能赢这个游戏。

本题的题目意思是把100换成一个变量叫做 maxChoosableInteger。问 player1 能不能赢这个游戏。

题解:这是一棵博弈树的问题。解空间如下图:

【LeetCode】一种博弈思路 minimax(共5题)

裸的dfs搜索方法如下:对于当前的局面,我们尝试用一个没有用过的数作为当前的解,然后dfs到下一个局面。

如果下个局面返回了false,就是对手不能赢,那我肯定非常高兴的马上返回了true,因为这个局面我能赢。(注意返回的时候要把当前局面用过的数字清空。回溯。不能忘。

但是如果下个局面返回了true,我就会认真反思自己,然后后悔当前局面的走法(是的,就是这么的无赖)去换一种新的走法。

那么对于当前局面的前一个局面来说,对手看到我返回了true,那他也可以反悔啊,他内心os:老子也不这么走了,我也要换一个走法。于是他就继续遍历他解空间的下一个解,直到他在当前空间找到了一个解,这个解能让他在当前空间赢,或者他找遍了所有的可能解,都赢不了,他只好认输,"我在当前空间赢不了,我返回false"。

 1 class Solution {
 2 public:
 3     bool canIWin(int maxChoosableInteger, int desiredTotal) {
 4         if (desiredTotal <= 0) {return true;}
 5         if (maxChoosableInteger * (maxChoosableInteger + 1) / 2 < desiredTotal) {return false;}
 6         string used(maxChoosableInteger, '0');
 7         int sum = 0;
 8         return canIWin(maxChoosableInteger, desiredTotal, sum, used);
 9     }
10     bool canIWin(int maxChoosableInteger, int desiredTotal, int sum, string& used) {
11         if (sum >= desiredTotal) {return false;}
12         for (int i = 1; i <= maxChoosableInteger; ++i) {
13             if (used[i-1] == '1') { continue; } //如果当前的数用过了,那么就换下一个能用的数
14             used[i-1] = '1';
15             if (canIWin(maxChoosableInteger, desiredTotal, sum + i, used) == false) {
16                 //到这里需要回溯。如果下一个局面为false的话,就说明当前局面能赢。
17                 //但是你想象一下如果你是一个玩家,当对手告诉你这个局面对手能赢的时候,你会怎么做,
18                 //肯定是返回到一个有一个解-对手不能赢的层次,然后去dfs那个解空间。
19                 used[i-1] = '0'; 
20                 return true;
21             }
22             used[i-1] = '0';
23         }
24         return false;
25     }
26 };
View Code

相关文章:

  • 2021-06-23
  • 2021-10-08
  • 2021-06-14
  • 2022-12-23
  • 2021-07-16
  • 2021-05-06
  • 2022-12-23
  • 2021-06-09
猜你喜欢
  • 2021-05-25
  • 2022-12-23
  • 2022-12-23
  • 2021-06-07
  • 2022-12-23
  • 2021-12-08
相关资源
相似解决方案