标签:pen ica return guess strong 空间 问题 closed lap
【375】Guess Number Higher or Lower II
【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 能不能赢这个游戏。
题解:这是一棵博弈树的问题。解空间如下图:
裸的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 };
再加上可以记忆化或者状态压缩的技巧。用个memo。
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, 0); 9 } 10 unordered_map<string, bool> memo; 11 bool canIWin(int maxChoosableInteger, int desiredTotal, int sum, string& used, int player) { 12 if (sum >= desiredTotal) {return false;} 13 if (memo.find(used) != memo.end()) {return memo[used];} 14 string key = used; 15 memo[key] = false; 16 for (int i = 1; i <= maxChoosableInteger; ++i) { 17 if (used[i-1] == ‘1‘) { continue; } 18 used[i-1] = ‘1‘; 19 if (canIWin(maxChoosableInteger, desiredTotal, sum + i, used, 1 - player) == false) { 20 memo[key] = true; 21 used[i-1] = ‘0‘; 22 return true; 23 } 24 used[i-1] = ‘0‘; 25 } 26 return false; 27 } 28 };
【486】Predict the Winner
【843】Guess the Word
【913】Cat and Mouse
标签:pen ica return guess strong 空间 问题 closed lap
原文地址:https://www.cnblogs.com/zhangwanying/p/9964702.html