leetcode 416

在 "100 game" 这个游戏中,两名玩家轮流选择从 1 到 10 的任意整数,累计整数和,先使得累计整数和 达到或超过  100 的玩家,即为胜者。

如果我们将游戏规则改为 “玩家 不能 重复使用整数” 呢?

例如,两个玩家可以轮流从公共整数池中抽取从 1 到 15 的整数(不放回),直到累计整数和 >= 100。

给定两个整数 maxChoosableInteger (整数池中可选择的最大数)和 desiredTotal(累计和),若先出手的玩家是否能稳赢则返回 true ,否则返回 false 。假设两位玩家游戏时都表现 最佳 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/can-i-win
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

 

 

 1 class Solution {
 2     // 保存之前判断的结果,防止重复计算
 3     Map<Integer, Boolean> map = new HashMap<Integer, Boolean>();
 4 
 5     public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
 6         // 当整数池的所有整数相加都没有超过预设值,则返回false
 7         if ((1 + maxChoosableInteger) * (maxChoosableInteger) / 2 < desiredTotal) {
 8             return false;
 9         }
10         return dfs(maxChoosableInteger, 0, desiredTotal, 0);
11     }
12 
13     public boolean dfs(int maxChoosableInteger, int usedNumbers, int desiredTotal, int currentTotal) {
14         if (!map.containsKey(usedNumbers)) {
15             boolean res = false;
16             // 遍历整数池
17             for (int i = 0; i < maxChoosableInteger; i++) {
18                 // 判断改整数是否使用过
19                 if (((usedNumbers >> i) & 1) == 0) {
20                     // 如果该整数加上之前的sum超过了预设值,则中断循环,返回true
21                     if (i + 1 + currentTotal >= desiredTotal) {
22                         res = true;
23                         break;
24                     }
25                     // 判断对手是否一定会输
26                     if (!dfs(maxChoosableInteger, usedNumbers | (1 << i), desiredTotal, currentTotal + i + 1)) {
27                         res = true;
28                         break;
29                     }
30                 }
31             }
32             // 更新,这次操作的结果
33             map.put(usedNumbers, res);
34         }
35         // 返回先手玩家一定会赢或者输
36         return map.get(usedNumbers);
37     }
38 }

 

posted @   牵魂  阅读(18)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示