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 }
  • 相关阅读:
    解决ubuntu不能安装g++的问题
    解决VMware虚拟机不能上网的问题
    打开vmvare出现The VMware Authorization Service is not running。
    word2-寻找社交新浪微博中的目标用户
    新浪云计算SAE部署代码过程
    Python如何调用新浪api接口的问题
    work1-英语辅导班在线报名系统
    Mysql对自增主键ID进行重新排序
    如何使用LIBSVM,从安装到基本实例使用
    laravel怎么创建一个简单的blog
  • 原文地址:https://www.cnblogs.com/codeskiller/p/6482364.html
Copyright © 2011-2022 走看看