gpt4 book ai didi

algorithm - Haskell:如何内存这个算法?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:52:45 28 4
gpt4 key购买 nike

我把这个解决方案写到 coin change problem on HackerRank :

makeChange :: Int -> [Int] -> Int
makeChange n ys = go n (sort ys)
where go _ [] = 0
go n (x:xs)
| x == n = 1
| x > n = 0
| otherwise = (makeChange n xs) + (makeChange (n - x) (x:xs))

但是它会在一些较大的测试用例上超时。我看到了this关于使用 let 绑定(bind)实现记忆化的文章,但它主要让我头疼,我不确定我将如何在这里实现它。有帮助吗?

我重写了它并获得了显着的性能改进,但我仍然在黑客排名练习上超时:

makeChange' :: Int -> [Int] -> Int
makeChange' =
let go _ [] = 0
go n (x:xs)
| x == n = 1
| x > n = 0
| otherwise = (makeChange' n xs) + (makeChange' (n - x) (x:xs))
in go

f (x:y:xs) = makeChange' x ys
where ys = sort xs
main = interact $ show . f . map read . words

我将预排序移到了一个中间函数 f 中,我也用它来处理来自 Hacker Rank 的输入。他们给你一个字符串,其中包含更改目标、更改数组的长度和更改单元数组。我使用 f 从输入中删除长度。

最佳答案

这个问题不需要需要内存。如果a 是一个无限长度 列表,其中a !! n 是总计 n 总和的方法的总数,你得到一个新的值(value) x 的独特硬币,你可以使用以下事实将列表 a 更新为新列表 b:

  • x元素不会改变;因为,您不能将新硬币用于小于 x 的金额。所以,取 xa
  • 对于剩余的元素:

    b(n) = a(n) + b(n - x)

    第一个加数表示根本不使用新硬币,第二个加数表示至少使用一次。

这可以简单地使用右折来实现,初始值为 [1, 0, 0, ...],因为没有硬币,您可能赚到的唯一总和为零。 Haskell 惰性在这里也非常有用:

solve :: Int -> [Int] -> Int
solve n xs = (foldr go (1:repeat 0) xs) !! n
where go x a = let b = (take x a) ++ zipWith (+) b (drop x a) in b

然后:

\> solve 4 [1, 2, 3]
4
\> solve 10 [2, 5, 3, 6]
5

如问题中的示例。

关于algorithm - Haskell:如何内存这个算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50313813/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com