• 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 }
  • 相关阅读:
    linux远程桌面连接 VNC Server
    linux内核 mtd分区
    STC15控制数码管 38译码器
    DS12C887实时时钟
    printf打印字节调试
    LED 控制卡 单元板 接口引脚定义
    linux守护进程start-stop-daemon启动服务
    相机速率计算
    CodeWarrior IDE烧写介绍
    让 Web 站点崩溃最常见的七大原因
  • 原文地址:https://www.cnblogs.com/codeskiller/p/6482364.html
Copyright © 2020-2023  润新知