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 }
  • 相关阅读:
    #include "stdafx.h" 错误?
    扩频技术
    求数组中只出现一次的数字(算法)
    1.3一摞烙饼的排序
    嵌套类
    企业级邮件服务软件推荐
    关于Linq To Sql中Detach方法和一个公共基类
    asp.net(c#) 将dbf转换为xls或wps,并将数据的列名改成中文;并判断本机是否安装office2003,2007和wps2007,2010
    一句代码解决IE8兼容问题(兼容性视图)
    asp.net(C#)套用模板操作Excel
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/6108137.html
Copyright © 2011-2022 走看看