我正在尝试以下问题:
两个玩家从一堆硬币开始,每个玩家都可以选择从这堆硬币中取出一个或两个硬币。取出最后一个硬币的玩家输。
我提出了以下简单的递归实现(playgound):
func gameWinner(coinsRemaining int, currentPlayer string) string {
if coinsRemaining <= 0 {
return currentPlayer
}
var nextPlayer string
if currentPlayer == "you" {
nextPlayer = "them"
} else {
nextPlayer = "you"
}
if gameWinner(coinsRemaining-1, nextPlayer) == currentPlayer || gameWinner(coinsRemaining-2, nextPlayer) == currentPlayer {
return currentPlayer
} else {
return nextPlayer
}
}
func main() {
fmt.Println(gameWinner(4, "you")) // "them"
}
以上代码工作正常。
然而,当我通过实现记忆化(见下文,或on the playgound)来改进这个解决方案时,我得到了错误的答案。
func gameWinner(coinsRemaining int, currentPlayer string, memo map[int]string) string {
if coinsRemaining <= 0 {
return currentPlayer
}
var nextPlayer string
if currentPlayer == "you" {
nextPlayer = "them"
} else {
nextPlayer = "you"
}
if _, exists := memo[coinsRemaining]; !exists {
if gameWinner(coinsRemaining-1, nextPlayer, memo) == currentPlayer || gameWinner(coinsRemaining-2, nextPlayer, memo) == currentPlayer {
memo[coinsRemaining] = currentPlayer
} else {
memo[coinsRemaining] = nextPlayer
}
}
return memo[coinsRemaining]
}
func main() {
memo := make(map[int]string)
fmt.Println(gameWinner(4, "you", memo))
}
如果能帮助我们理解为什么第二个实现返回的值与第一个不同,我们将不胜感激!
1条答案
按热度按时间jvlzgdj91#
你的记忆是错误的:赢家不仅取决于当前硬币的数量,还取决于轮到谁。2你需要如下的东西: