【LeetCode 464】Can I Win
https://leetcode.com/problems/can-i-win/
思路:
1. 用checked的二进制形式表示第i个数被选取
2. 对每个数字进行dfs,dfs每次返回当前checked状态下是否能win
3. dfs会产生重复的结果,对每次dfs的结果用c[checked]记录
class Solution { public: int checked; //每个位为0或1,分别代表对应的数字是否被选择 map<int, int> c; //对当前的可选数字和当前的目标,是否可以成功 <可选数字,是否成功0、1> bool canIWin(int maxChoosableInteger, int desiredTotal) { int sum = (1 + maxChoosableInteger)*maxChoosableInteger / 2; if (sum<desiredTotal) return false; if (desiredTotal <= 0) return true; if (maxChoosableInteger >= desiredTotal) return true; return helper(maxChoosableInteger, desiredTotal,0); } bool helper(int max, int desire,int recursiveLayer) { if (desire <= 0) return false; //查备忘录 if (c.find(checked) == c.end()) //注意:只能用find { for (int i = 1;i <= max;i++) { //当前数字没有被选择 if (((checked) & (1<<i)) == 0) //确认某一个位是否为1 { //锁定当前数字 checked += 1 << i; if (helper(max, desire - i, recursiveLayer+1) == false) //测试当前的i,如果成功,则立即返回true,否则测试下一个i,最终返回false { //释放当前数字 checked -= 1 << i; //添加备忘录 注意:在释放数字后添加备忘录! c[checked] = 1; cout << "layer:" << recursiveLayer << "select:" << i << endl; return true; } else { //释放当前数字 checked -= 1 << i; //添加备忘录 c[checked] = 0; } } } return false; } else { if (c[checked] == 1) return true; if (c[checked] == 0) return false; } } };