Project Euler 297
题目
Zeckendorf Representation
Each new term in the Fibonacci sequence is generated by adding the
previous two terms.
Starting with and , the first terms will be: .
Every positive integer can be uniquely written as a sum of
nonconsecutive terms of the Fibonacci sequence. For example, .
Such a sum is called the Zeckendorf representation
of the number.
For any integer , let
be the number of terms in the
Zeckendorf representation of .
Thus,
etc.
Also, for .
Find for .
齐肯多夫定理
齐肯多夫定理 ,任何一个数 ,都可以表示成多个不相邻 斐波那契数之和,并且这种表示方法是唯一 的。
解决方案
令
对于一个数 求它的齐肯多夫表示法,不难想到使用贪心的方法:从大到小 枚举斐波那契数 ,如果 不超过 ,那么记录下 ,并从 减去 ,否则跳过,直到 变成 .
当我们计算 时,记 为不超过 的最大斐波那契数。在 这一部分数中,不难发现, 这一部分永远不会用到 来表示。而 中的所有数都会用到 表示,而将这一部分数都用 表示后,接下来就以同样的思想考虑 这一部分,也就是 。
那么,不难写出 的递推式:
使用记忆化的递归可以快速求出 .
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 N = 10 ** 17 N -= 1 f = [1 , 2 ] mp = {0 : 0 } while True : f.append(f[-1 ] + f[-2 ]) if f[-1 ] > N: break def dfs (n: int ): if n in mp.keys(): return mp[n] p = 0 while p + 1 < len (f) and f[p + 1 ] <= n: p += 1 ans = dfs(f[p] - 1 ) + dfs(n - f[p]) + n - f[p] + 1 mp[n] = ans return ans ans = dfs(N) print (ans)