Dynamic Programming - 375. Guess Number Higher or Lower II
375. Guess Number Higher or Lower II
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.
思路:
这一题是374题的升级题目,374只需要用一个二分查找就能在不超时的情况下猜中数字,而这题是在猜数字的情况下,猜错了就得付钱,求的是保证能赢花出去的钱,做法是使用动态规划来做,在1-n个数里面,我们任意猜一个数(设为i),保证获胜所花的钱应该为 i + max(w(1 ,i-1), w(i+1 ,n)),这里w(x,y))表示猜范围在(x,y)的数保证能赢应花的钱,则我们依次遍历 1-n作为猜的数,求出其中的最小值即为答案。
代码:
go :
func getMoneyAmount(n int) int {
var dp = make([][]int, n+1)
for i := range dp {
dp[i] = make([]int, n+1)
}
for j := 2; j <= n; j++ {
for i := j-1; i > 0; i-- {
globalMin :=math.MaxInt32
for k := i+1; k < j; k++ {
localMax := k + max(dp[i][k-1], dp[k+1][j])
globalMin = min(globalMin, localMax)
}
if i+1 == j {
dp[i][j] = i
} else {
dp[i][j] = globalMin
}
}
}
return dp[1][n];
}
// recursive dp solution
func getMoneyAmount(n int) int {
var dp = make([][]int, n+1)
for i := range dp {
dp[i] = make([]int, n+1)
}
return dfs(1, n, &dp)
}
func dfs(start, end int, dp *[][]int) int {
if start >= end {
return 0
}
if (*dp)[start][end] != 0 {
return (*dp)[start][end]
}
res := math.MaxInt32
for i := start; i <= end; i++ {
res = min(res, i + max(dfs(start, i - 1, dp), dfs(i + 1, end, dp)))
}
(*dp)[start][end] = res
return res;
}
func min(i, j int) int {
if i < j {
return i
}
return j
}
func max(i, j int) int {
if i > j {
return i
}
return j
}