递归关系的一般公式?

时间:2016-11-27 13:33:36

标签: algorithm formula recurrence

我正在解决一个编码问题,并找出以下关系来找出可能的安排数量:

one[1] = two[1] = three[1] = 1

one[i] = two[i-1] + three[i-1]

two[i] = one[i-1] + three[i-1]

three[i] = one[i-1] + two[i-1] + three[i-1]

我可以轻松地使用 for循环来查找单个数组的值,直到n,但n的值为{{1}的顺序我将无法从10^9迭代到如此庞大的数字。

对于1的每个值,我需要在n时间内输出(one[n] + two[n] + three[n]) % 10^9+7的值。

一些结果:

  • 对于n = 1,结果= 3
  • 对于n = 2,结果= 7
  • 对于n = 3,结果= 17
  • 对于n = 4,结果= 41

在花费数小时后,我无法找到上述O(1)的通用公式。有人可以帮助我。

修改:

n

所以,n = 1, result(1) = 3 n = 2, result(2) = 7 n = 3, result(3) = result(2)*2 + result(1) = 17 n = 4, result(4) = result(3)*2 + result(2) = 41 或     result(n) = result(n-1)*2 + result(n-2)

1 个答案:

答案 0 :(得分:2)

您可以使用矩阵来表示递归关系。 (我已将onetwothree重命名为abc

(a[n+1]) = ( 0 1 1 ) (a[n])
(b[n+1])   ( 1 0 1 ) (b[n])
(c[n+1])   ( 1 1 1 ) (c[n])

通过这种表示,通过矩阵指数(以大数为模),通过平方指数计算大n的值是可行的。那将在O(log n)时间内给你结果。

(a[n]) = ( 0 1 1 )^(n-1) (1)
(b[n])   ( 1 0 1 )       (1)
(c[n])   ( 1 1 1 )       (1)

这里有一些Python从头开始实现这一点:

# compute a*b mod K where a and b are square matrices of the same size
def mmul(a, b, K):
    n = len(a)
    return [
        [sum(a[i][k] * b[k][j] for k in xrange(n)) % K for j in xrange(n)]
        for i in xrange(n)]

# compute a^n mod K where a is a square matrix
def mpow(a, n, K):
    if n == 0: return [[i == j for i in xrange(len(a))] for j in xrange(len(a))]
    if n % 2: return mmul(mpow(a, n-1, K), a, K)
    a2 = mpow(a, n//2, K)
    return mmul(a2, a2, K)

M = [[0, 1, 1], [1, 0, 1], [1, 1, 1]]

def f(n):
    K = 10**9+7
    return sum(sum(a) for a in mpow(M, n-1, K)) % K

print f(1), f(2), f(3), f(4)
print f(10 ** 9)

输出:

3 7 17 41
999999966

即使对于n = 10 ** 9的情况,它也能立即有效运行。