博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode] 375. Guess Number Higher or Lower II 猜数字大小 II
阅读量:5452 次
发布时间:2019-06-15

本文共 2594 字,大约阅读时间需要 8 分钟。

We 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.

Hint:

  1. The best strategy to play the game is to minimize the maximum loss you could possibly face. Another strategy is to minimize the expected loss. Here, we are interested in thefirst scenario.
  2. Take a small example (n = 3). What do you end up paying in the worst case?
  3. Check out  if you're still stuck.
  4. The purely recursive implementation of minimax would be worthless for even a small n. You MUST use dynamic programming.
  5. As a follow-up, how would you modify your code to solve the problem of minimizing the expected loss, instead of the worst-case loss?

Credits:

Special thanks to  and  for adding this problem and creating all test cases.

 的拓展,这题每猜一次要给一次和猜的数字相等的钱,求出最少多少钱可以保证猜出。

解法:根据提示,这道题需要用到。要用DP来做,需要建立一个二维的dp数组,其中dp[i][j]表示从数字i到j之间猜中任意一个数字最少需要花费的钱数。需要遍历每一段区间[j, i],维护一个全局最小值global_min变量,然后遍历该区间中的每一个数字,计算局部最大值local_max = k + max(dp[j][k - 1], dp[k + 1][i]),然后更新全局最小值。

参考:

 
Python:
class Solution(object):    def getMoneyAmount(self, n):        """        :type n: int        :rtype: int        """        pay = [[0] * n for _ in xrange(n+1)]        for i in reversed(xrange(n)):            for j in xrange(i+1, n):                pay[i][j] = min(k+1 + max(pay[i][k-1], pay[k+1][j]) \                                for k in xrange(i, j+1))        return pay[0][n-1]

C++:  

class Solution {public:    int getMoneyAmount(int n) {        vector
> pay(n + 1, vector
(n)); for (int i = n - 1; i >= 0; --i) { for (int j = i + 1; j < n; ++j) { pay[i][j] = numeric_limits
::max(); for (int k = i; k <= j; ++k) { pay[i][j] = min(pay[i][j], k + 1 + max(pay[i][k - 1], pay[k + 1][j])); } } } return pay[0][n - 1]; }};

   

类似题目:

 

 

转载于:https://www.cnblogs.com/lightwindy/p/8636356.html

你可能感兴趣的文章
循环冗余校验(CRC)算法入门引导
查看>>
Swift继承的用法
查看>>
【[六省联考2017]组合数问题】
查看>>
数据结构与算法学习 第1季02 链表的基本功能 C++实现
查看>>
Oracle Listener
查看>>
java String spilt 问题
查看>>
【P3056】【USACO12NOV】笨牛Clumsy Cows
查看>>
准标识符(Quasi-dientifier, QI)
查看>>
深入理解VMware虚拟机网络通信原理
查看>>
Linux命令——find/grep
查看>>
TJU1016
查看>>
HttpClientUitl工具类
查看>>
Could not find or load main class
查看>>
VC 预定义宏
查看>>
indexOf()
查看>>
dom4j对xml读取操作
查看>>
Yii2.0实现微信公众号后台开发
查看>>
Shell 传递参数
查看>>
Ibatis 泛型化dao模版
查看>>
hrbust 1133 (kruskal)
查看>>