zoukankan      html  css  js  c++  java
  • Leetcode: Guess Number Higher or Lower II

    e are playing the Guess Game. The game is as follows:
    
    I pick a number from 1 to n. You have to guess which number I picked.
    
    Every time you guess wrong, I'll tell you whether the number I picked is higher or lower.
    
    However, when you guess a particular number x, and you guess wrong, you pay $x. You win the game when you guess the number I picked.
    
    Example:
    
    n = 10, I pick 8.
    
    First round:  You guess 5, I tell you that it's higher. You pay $5.
    Second round: You guess 7, I tell you that it's higher. You pay $7.
    Third round:  You guess 9, I tell you that it's lower. You pay $9.
    
    Game over. 8 is the number I picked.
    
    You end up paying $5 + $7 + $9 = $21.
    Given a particular n ≥ 1, find out how much money you need to have to guarantee a win.

    Clarification of the problem: https://discuss.leetcode.com/topic/68252/clarification-on-the-problem-description-problem-description-need-to-be-updated

    It is actually confusing that the example shown in the problem description is not the best stragety to guess the final target number, and the problem itself is asking for the lowest cost achieved by best guessing strategy. We can also understand in this way, your guessing strategy is the best, but your luck is the worst(every time your guess is wrong until there's no possibility to make mistake)
    The example description should be updated.

    ---POSSIBLY, it can also add some example about the BEST Strategy---
    The example description should be:

    first introducebest strategyto guess:

      1. for one number, like 1, best strategy is 0$
      2. for two number, like 3,4, best strategy is 3$, which can be understood in this way: you have two way to guess: a) start by guess 4 is the target, (the worst case is) if wrong, you get charged $4, then immediately you know 3 is the target number, get get charged $0 by guessing that, and finally you get charged $4. b) similarly, if you start by 3, (the worst case is) if wrong, you get charged $3, then you immediately know that 4 is the target number, and get charged $0 for guessing this, and finally you get charged $3. In summary:
        range ---------> best strategy cost
        3, 4 ---------> $3
        5, 6 ---------> $5
        ...
      3. for three number, the best strategy is guess the middle number first, and (worst case is) if wrong, you get charged that middle number money, and then you immediately know what target number is by using "lower" or "higher" response, so in summary:
        range ---------> best strategy cost
        3, 4, 5 ---------> $4
        7, 8, 9 ---------> $8
        ...
      4. for more numbers, it can simply be reduced them into smaller ranges, and here is why DP solution make more sense in solving this.
        suppose the range is [start, end]
        the strategy here is to iterate through all number possible and select it as the starting point, say for any k between start and end, the worst cost for this is: k+DP( start, k-1 ) + DP(k+1, end ), and the goal is minimize the cost, so you need the minimum one among all those k between start and end

    Another analysis: 

    The best strategy to play the game is to minimize the maximum loss you could possibly face. 

    Definition of dp[i][j]: minimum number of money to guarantee win for subproblem [i, j].

    Target: dp[1][n]

    Corner case: dp[i][i] = 0 (because the only element must be correct)

    Equation: we can choose k (i<=k<=j) as our guess, and pay price k. After our guess, the problem is divided into two subproblems. Notice we do not need to pay the money for both subproblems. We only need to pay the worst case (because the system will tell us which side we should go) to guarantee win. So dp[i][j] = min (i<=k<=j) { k + max(dp[i][k-1], dp[k+1][j]) }

     1 public class Solution {
     2     public int getMoneyAmount(int n) {
     3         if (n == 1) return 0;
     4         int[][] dp = new int[n+1][n+1];
     5         
     6         for (int len=1; len<=n-1; len++) {
     7             for (int i=1; i+len<=n; i++) {
     8                 int j = i + len;
     9                 dp[i][j] = Integer.MAX_VALUE;
    10                 for (int k=i; k<=j; k++) {
    11                     dp[i][j] = Math.min(dp[i][j], 
    12                                         k+Math.max(k==i? 0 : dp[i][k-1], 
    13                                                    k==j? 0 : dp[k+1][j]));
    14                 }
    15             }
    16         }
    17         return dp[1][n];
    18     }
    19 }
  • 相关阅读:
    java开发中的常见类和对象-建议阅读时间3分钟
    周末学习-泛型-就是传入什么类型就是什么类型-花了一个半小时
    实习第二天-String对象的不可变性-未解决
    实习第二天-java参数传递-精华在文章最后2句话
    实习第二天-对象-对象引用-引用变量-精-精-精-下雨天
    实习第一天:try和catch的使用
    实习第二天-今年第一场雨-方法的重载(马上想到println()函数和abs(函数))
    实习第一周第一天:接口 extends是继承类,implement是实现接口,原接口里面的方法填充,方法名也是不变,重写override是父类的方法名不变,把方法体给改了
    实习第一天:static 声明的 变量和 方法
    JavaWeb学习总结(二)-修改Tomcat服务器的端口(半年之后再总结)
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/6108137.html
Copyright © 2011-2022 走看看