zoukankan      html  css  js  c++  java
  • 464. Can I Win

    In the "100 game," two players take turns adding, to a running total, any integer from 1..10. The player who first causes the running total to reach or exceed 100 wins.

    What if we change the game so that players cannot re-use integers?

    For example, two players might take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total >= 100.

    Given an integer maxChoosableInteger and another integer desiredTotal, determine if the first player to move can force a win, assuming both players play optimally.

    You can always assume that maxChoosableInteger will not be larger than 20 and desiredTotal will not be larger than 300.

    Example

    Input:
    maxChoosableInteger = 10
    desiredTotal = 11
    
    Output:
    false
    
    Explanation:
    No matter which integer the first player choose, the first player will lose.
    The first player can choose an integer from 1 up to 10.
    If the first player choose 1, the second player can only choose integers from 2 up to 10.
    The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal.
    Same with other integers chosen by the first player, the second player will always win.

    本题难度挺高的,用的是动态规划方法解决,动态规划是原问题可以分解为若干规模较小的子问题,并且具有重叠子问题和最优子结构的性质。首先要思考状态方程,状态方程是desiredTotal-i,比较不容易看出来
    为了避免重叠子问题,用了hashmap来存储返回true,false的子问题的值,这里面有一个比较奇妙的地方是,将布尔类型的used数组转换成一个integer。然后把这个integer存储在hashmap里面,代码如下:
     1 public class Solution {
     2     public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
     3         Map<Integer,Boolean> map = new HashMap<>();
     4         boolean[] used = new boolean[maxChoosableInteger+1];
     5         int sum = (1+maxChoosableInteger)*maxChoosableInteger/2;
     6         if(sum<desiredTotal) return false;
     7         if(desiredTotal<=0) return true;
     8         return helper(map,used,desiredTotal);
     9     }
    10     public boolean helper(Map<Integer,Boolean> map,boolean[] used,int desiredTotal){
    11         if(desiredTotal<=0) return false;
    12         int key = format(used);
    13         if(!map.containsKey(key)){
    14             for(int i=1;i<used.length;i++){
    15                 if(!used[i]){
    16                     used[i] = true;
    17                     if(!helper(map,used,desiredTotal-i)){
    18                         used[i] = false;
    19                         map.put(key,true);
    20                         return true;
    21                     }
    22                     used[i] = false;
    23                 }
    24             }
    25             map.put(key,false);
    26         }
    27         return map.get(key);
    28     }
    29     public int format(boolean[] used){
    30         int num = 0;
    31         for(int i=0;i<used.length;i++){
    32             num<<=1;
    33             if(used[i]) num|=1;
    34         }
    35         return num;
    36     }
    37 }
  • 相关阅读:
    软件工程2019实践第一次作业
    Maven环境的搭建
    TomCat控制台中文乱码及IDEA设置为UTF-8
    将win10永久激活为专业工作站版(图文详细教程)
    [软件技巧]manjaro gnome中修改屏幕缩放比例
    第一次个人编程作业
    百度的TTS API
    第一次软件工程实践作业
    MySQL触发器的操作
    Anaconda使用conda activate激活环境报错Your shell has not been properly configured to use 'conda activate'.
  • 原文地址:https://www.cnblogs.com/codeskiller/p/6482364.html
Copyright © 2011-2022 走看看