转换朴素递归硬币问题时记忆错误
短信预约 -IT技能 免费直播动态提醒
php小编鱼仔在解决朴素递归硬币问题时,不小心犯了一个记忆错误。这个问题是指给定一定数量的硬币和一个目标金额,要求计算出组成目标金额的所有不同组合方式。通常,我们可以使用递归来解决这个问题,但我的记忆错误导致了错误的计算结果。在这篇文章中,我将重新解释正确的解决方法,并提供一些实用的技巧来避免类似的错误。
问题内容
我正在尝试解决以下问题:
两名玩家从一堆硬币开始,每个玩家都可以选择从硬币堆中取出一枚或两枚硬币。拿走最后一枚硬币的玩家就输了。
我想出了以下简单的递归实现 (游乐场):
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"
}
上面的代码工作正常。
但是,当我通过实现记忆化(见下文或在操场上)来改进此解决方案时,我得到了错误的答案。
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))
}
任何关于为什么第二个实现返回与第一个实现不同的值的帮助将不胜感激!
解决方法
你的记忆是错误的:获胜者不仅取决于当前的硬币数量,还取决于轮到谁。您需要类似以下内容:
type state struct {
coinsRemaining int
currentPlayer string
}
memo := make(map[state]string)
以上就是转换朴素递归硬币问题时记忆错误的详细内容,更多请关注编程网其它相关文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341