题目描述
思路
这是一道dp的题目,我们用dp(i, j)表示在范围[i, j]内确保胜利的最少金额,那么目标就是计算dp(1, n)
假设第一次猜的数字是x且猜错了,那么需要先支付金额x, 然后继续猜。那么就有两种情况:
- 当x大于所选的数字, 那么为了确保胜利,还需要支付dp(1, x - 1)
- 当x小于所选的数字,那么为了确保胜利,还需要支付do(x + 1, n)
为了确保任何情况下都能保证胜利,就应该考虑最坏的情况,也就是要取上述两种情况的最大值,即dp(1, n) = x + max(dp(1, x-1), dp(x+1,n))
为了确保胜利金额最小化,我们要考虑所有x的情况,即
dp(1, n) = min(x + max(dp(1, x-1), dp(x+1,n))), 其中1 ≤ x ≤ n
代码实现(py3)
class Solution:
def getMoneyAmount(self, n: int) -> int:
dp = [[0] * (n + 1) for _ in range(n+1)]
for i in range(n - 1, 0, -1):
for j in range(i + 1, n + 1):
min = 0xffff
for k in range(i, j):
temp = k + max(dp[i][k-1],dp[k+1][j])
if temp < min:
min = temp
dp[i][j] = min
return dp[1][n]
时间复杂度:O(n^3)
空间复杂度:O(n^2)