• [leetcode] 464. Can I Win (Medium)


    原题链接


    两个人依次从1~maxNum中选取数字(不可重复选取同一个),累和。当一方选取数字累和后结果大于等于给定的目标数字,则此人胜利。
    题目给一个maxNum和targetNum,要求判断先手能否胜利。

    思路:
    首先判断两种特殊条件:

    1. 可选最大值大于等于目标值,直接返回true。
    2. 其中一个人可选的最大值小于目标值,直接返回false。

    具体再看题目,题目给出maxNum不大于20,则可状态压缩为一个int(32位)来保存每个数字是否被使用过(题解中利用1-32位进行存储)。
    利用一个map存储选取每一个数字的情况,每一次选择前进行判断,如若已经有过选取该数字的情况,则返回map里的值。
    遍历i从1到maxN,考虑选取i的情况:
    判断先手胜利条件:

    1. 选上i数字后,大于等于目标值可胜利。( i >= targetN )
    2. 选上i数字后,后手输了。( helper(maxN, targetN - i, mask | visited) == false) )
      返回true。
      其他情况下,则表示先手输,返回false。

    Runtime: 137 ms, faster than 43.48% of Java

    class Solution {
        public Map<Integer, Boolean> m = new HashMap<Integer, Boolean>();
    
        public boolean helper(int maxN, int targetN, int visited) {
            if (m.containsKey(visited))
                return m.get(visited);
            for (int i = 1; i <= maxN; i++) {
                int mask = (1 << i);
                if ((mask & visited) == 0 && (i >= targetN || helper(maxN, targetN - i, mask | visited) == false)) {
                    m.put(visited, true);
                    return true;
                }
            }
            m.put(visited, false);
            return false;
        }
    
        public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
            if (maxChoosableInteger >= desiredTotal)
                return true;
            if ((1 + maxChoosableInteger) * maxChoosableInteger / 2 < desiredTotal)
                return false;
            return helper(maxChoosableInteger, desiredTotal, 0);
        }
    }
    
    
  • 相关阅读:
    bzoj 1208: [HNOI2004]宠物收养所
    bzoj 1207: [HNOI2004]打鼹鼠
    【NOIP模拟赛】小奇的矩阵
    【NOIP模拟赛】小奇挖矿 2
    Making the Grade POJ
    POJ 3616Milking Time
    [USACO08JAN]电话线Telephone Lines
    Radar Installation POJ
    Warfare And Logistics UVA
    【NOIP2009】最优贸易
  • 原文地址:https://www.cnblogs.com/ruoh3kou/p/9942431.html
Copyright © 2020-2023  润新知