我刚刚遇到一个具有挑战性的问题(来自编程竞赛实践),其中包含以下递归序列
给定 3 个数字mnk找到元素 a[k] 其中
a[0] = m
a[1] = n
a[i] = a[i-1] + a[i-2] ; if floor(i/2) mod 2 = 1
a[i] = a[i-1] - a[i-4] ; if floor(i/2) mod 2 = 0
示例:对于 m=2 n=3 k=6 答案为 9
a[0] = 2
a[1] = 3
a[2] = 3 + 2 = 5
a[3] = 5 + 3 = 8
a[4] = 8 - 2 = 6
a[5] = 6 - 3 = 3
a[6] = 3 + 6 = 9
...
这就是我生成序列的方式(这显然会消耗大量堆栈并且即使对于前 100 个元素也非常慢)
1 fbm :: Int → Int → Int → Int
2 fbm m n 0 = m
3 fbm m n 1 = n
4 fbm m n x = let a = fbm m n (x-1)
5 b = fbm m n (x-2)
6 c = fbm m n (x-4)
7 in case (x `div` 2) `mod` 2 of
8 1 → a + b
9 0 → a - c
10
11 fbs m n = map (λx→fbm m n x) [0..]
由于需要在大(〜1000+)索引处查找元素的问题。我尝试通过尝试仅在具有 4 个输入的函数上限制计算并在列表上递归地应用具有4 个元素窗口的函数但无法成功实现它们中的任何一个(这意味着我无法弄清楚如何做)
fs1 = map fst $ iterate next (a,b)
where next (a,b) = something
fs2 = m:n:scanl (gen) 2 fs2
where gen [a,b,c,d] = something
fs3 = scanl (genx m n 0 0) (repeat 0)
where genx a b c d = something
问题1:我的任何方法都是解决这个问题的好方法吗?(+请给我一个如何做的例子)
问题2:如果我走错了路,你会如何解决这种问题?