题目描述
题目链接:375. Guess Number Higher or Lower II
We are playing the Guessing Game. The game will work as follows:
- I pick a number between
1
andn
.- You guess a number.
- If you guess the right number, you win the game.
- If you guess the wrong number, then I will tell you whether the number I picked is higher or lower, and you will continue guessing.
- Every time you guess a wrong number
x
, you will payx
dollars. If you run out of money, you lose the game. Given a particularn
, return the minimum amount of money you need to guarantee a win regardless of what number I pick.
例子
例子 1
Input:
n = 10
Output:16
Explanation: The winning strategy is as follows:
- The range is [1,10]. Guess 7.
- If this is my number, your total is $0. Otherwise, you pay $7.
- If my number is higher, the range is [8,10]. Guess 9.
- If this is my number, your total is $7. Otherwise, you pay $9.
- If my number is higher, it must be 10. Guess 10. Your total is $7 + $9 = $16.
- If my number is lower, it must be 8. Guess 8. Your total is $7 + $9 = $16.
- If my number is lower, the range is [1,6]. Guess 3.
- If this is my number, your total is $7. Otherwise, you pay $3.
- If my number is higher, the range is [4,6]. Guess 5.
- If this is my number, your total is $7 + $3 = $10. Otherwise, you pay $5.
- If my number is higher, it must be 6. Guess 6. Your total is $7 + $3 + $5 = $15.
- If my number is lower, it must be 4. Guess 4. Your total is $7 + $3 + $5 = $15.
- If my number is lower, the range is [1,2]. Guess 1.
- If this is my number, your total is $7 + $3 = $10. Otherwise, you pay $1.
- If my number is higher, it must be 2. Guess 2. Your total is $7 + $3 + $1 = $11. The worst case in all these scenarios is that you pay $16. Hence, you only need $16 to guarantee a win.
例子 2
Input:
n = 1
Output:0
Explanation:There is only one possible number, so you can guess 1 and not have to pay anything.
例子 3
Input:
n = 2
Output:1
Explanation: There are two possible numbers, 1 and 2.
- Guess 1.
- If this is my number, your total is $0. Otherwise, you pay $1.
- If my number is higher, it must be 2. Guess 2. Your total is $1. The worst case is that you pay $1.
Constraints
1 <= n <= 200
解题思路
这道题可以看到数据规模不大,我们可以考虑用暴力枚举的方法(相对高的时间复杂度,但不到指数级别)。然后这种求极值的题目可以从动态规划的思路去思考,考虑采用一个二维数组 minAmount
,其中 minAmount[left][right]
表示给定范围为 left
到 right
最坏情况下需要付出的成本。在对于一个给定范围内,我们可以枚举其中所有的位置进行猜测并对其进行更新,更新的逻辑是:
从猜测的位置左右两侧挑选一个更大的值作为最坏情况,加上猜测的值本身作为本次猜测能得到最小的保证赢的成本,并和当前成本进行比较取最小值。
minAmount[left][right] = min(minAmount[left][right], \
guess_num + \
max(minAmount[left][guess_num - 1],\
minAmount[guess_num + 1][right]));
具体代码如下:查表过程中需要考虑边界值。
#include <climits>
#include <cmath>
#include <vector>
class Solution {
public:
int getMoneyAmount(int n) {
std::vector<std::vector<int>> minAmount(
n + 1, std::vector<int>(n + 1, INT_MAX));
// if the length of range is 1, we will win at a guess, so no cost
for (int i = 1; i <= n; i++) minAmount[i][i] = 0;
for (int len = 2; len <= n; ++len) {
for (int left = 1; left <= n - len + 1; ++left) {
int right = left + len - 1;
for (int guess = left; guess <= right; ++guess) {
// choose worst scenarios from either left or right side of
// guessing
minAmount[left][right] = std::min(
minAmount[left][right],
guess + std::max(
lookupAmount(minAmount, left, guess - 1),
lookupAmount(minAmount, guess + 1, right)));
}
}
}
return minAmount[1][n];
}
private:
int lookupAmount(const std::vector<std::vector<int>>& minAmount, int l,
int r) {
if (l > r || l < 0 || r >= minAmount.size()) return 0;
return minAmount[l][r];
}
};
- 时间复杂度: O(n^3)
- 空间复杂度: O(n^2)
GitHub 代码同步地址: 375.GuessNumberHigherOrLowerIi.cpp
其他题目: GitHub: Leetcode-C++-Solution 博客: Leetcode-Solutions