我有一系列数字A. 有一个索引 - k ,它将作为参数传递给程序。 该系列是算术级数(d = 1),直到 k -th元素。例如:
0 = 0,A 1 = 1 [...] A k -1 =的ķ -1。
从那时起,每个元素都是最后 k 元素的总和。 例如:
k +3 = A 2 + A 3 + [...] + A <子>的ķ 2 子>
用户输入数字 n (和 k ,如上所述)。程序需要计算并返回所描述的A系列的 n 元素。
实施例: k = 5, n = 8
0 = 0 ,A 1 = 1 ,A 2 = 2 ,A 3 = 3 ,A 4 = 4 ,A < sub> 5 = 10 ,A 7 = 20 ,A 7 = 39 ,A 8 = 76
A = [0,1,2,3,4,10,20,39, 76 ]
n = 76
有什么想法?在过去的几天里,这一直困扰着我,但是数学从来都不是我的事情,所以我认为找到一个聪明的方法(除了有一个循环,当然 - 这听起来并不聪明)是一个大问题。 另外,对不起,如果我犯了任何错误,英语不是我的主要语言。
答案 0 :(得分:5)
在Oli Charlesworth的回答中稍微扩展,考虑向量
A n = [A n ,A n-1 ... A n -k + 1 ]
你知道吗
n = A n-1 + ... + A n-k
所以你可以用 A n-1 表示 A n
A n = B A n-1
其中 B 是 k x k 矩阵,其顶行为1,主对角线下方为1,其他地方为零。例如,对于 k = 4,您有
1 1 1 1
B = 1 0 0 0
0 1 0 0
0 0 1 0
现在已经解决了复发的问题
A n = B n-k + 1 A K-1 子>
与
A k-1 = [k-1,k-2,k-3 ... 2,1,0]
使用快速矩阵求幂算法,你需要做log( n - k + 1)矩阵乘法得到答案,这大约是log(< em> n ) n &gt;&gt; ķ。矩阵乘法的代价是 k 3 ,因此总复杂度为 k 3 log( n )
答案 1 :(得分:3)
我不知道你是否可以在没有循环的情况下做到这一点,但你肯定比O(n)时间复杂度更好。如果将此递归表示为矩阵运算(类似于that for the Fibaonacci sequence),则查找n
- 项将等效于矩阵的n
次幂,这可能是由fast exponentiation在O(log n)时间内完成。
答案 2 :(得分:0)
如果找到序列元素的封闭形式,可以在O(1)
中解决它。这是linear recurring sequences的一个非常简单的过程,它涉及使用生成函数。请参阅example for the Fibonacci sequence。
答案 3 :(得分:0)
@ChrisTaylor和@OliCharlesworth的快速矩阵取幂是可行的方法。找到@AdrianPanasiuk提到的封闭形式涉及找到想要取幂的矩阵的对角化。一个足够强大的库可能能为你做到这一点。
如果没有,生成函数和线性递归可归结为需要找到多项式的所有k个根 X ķ -x K-1 -...- 1 = 0 (包括复杂的根)。如果你标记根 [R <子> 1 子>,R <子> 2 子>,...,R <子>ķ子>, 那么你的解决方案就是形式 A n =Σ i = 1 n c i r i ñ。 为了找到c i 的值,你将为0≤n≤k-1插入已知的A n ,得到k个未知数的k个线性方程组。
如果你知道k≤4,那么这可能值得所有麻烦的唯一方法就是你可以提前完成所有可能的k值的所有数学运算(你将无法做到)求解更大k的多项式方程。如果你期望n的巨大价值。如果您期望大量用户查询。
答案 4 :(得分:-1)
如果你只写出系列的前几个术语,我想你会看到如何在恒定时间内计算出来:
0, 1, 1, 2, 4, 8, 16, 32, ...
所以我认为它是2 ^(n-2)(第一学期除外)。还是我误解了?
哦,我只是重新阅读并看到k可以变化 - 我给出了k = 2的答案?所以k = 3将是:
0, 1, 2, 3, 6, 12, 24, ... ?
肯定有封闭式解决方案;我想也许
k * 2^(n-k); n > k