0
点赞
收藏
分享

微信扫一扫

蓝桥杯算法提高VIP-递推求值

Xin_So 2022-02-14 阅读 55

题目描述

已知递推公式:

F(n, 1)=F(n-1, 2) + 2F(n-3, 1) + 5,

F(n, 2)=F(n-1, 1) + 3F(n-3, 1) + 2F(n-3, 2) + 3.

初始值为:F(1, 1)=2, F(1, 2)=3, F(2, 1)=1, F(2, 2)=4, F(3, 1)=6, F(3, 2)=5。

输入n,输出F(n, 1)和F(n, 2),由于答案可能很大,你只需要输出答案除以99999999的余数。

输入

输入第一行包含一个整数n。

输出

输出两行,第一行为F(n, 1)除以99999999的余数,第二行为F(n, 2)除以99999999的余数。

样例输入

4

样例输出

14
21

第一次尝试提交(不行)
def f(n, num):
    if n == 1 and num == 1:
        return 2
    if n == 1 and num == 2:
        return 3
    if n == 2 and num == 1:
        return 1
    if n == 2 and num == 2:
        return 4
    if n == 3 and num == 1:
        return 6
    if n == 3 and num == 2:
        return 5
    sum = 0
    if num == 1:
        sum = (sum + f(n - 1, 2) + 2 * f(n - 3, 1) + 5)%99999999
    elif num == 2:
        sum = (sum + f(n - 1, 1) + 3 * f(n - 3, 1) + 2 * f(n - 3, 2) + 3)%99999999
    return sum%99999999

n = int(input())
print(f(n,1))
print(f(n,2))

第二次提交(重点,学到的新方法)

先看看这篇文章
--------------矩阵的构造方法---------------

下面的方法类似于求斐波那契,将递归转化成矩阵相乘,然后矩阵相乘我们是可以用快速幂的方法求得的。

类似的,我们目的就是要得到下面这个公式,其中第1 个,第2 个就是要求的值

 [f(n-1,1),f(n-1,2),f(n-2,1),f(n-2,2),f(n-3,1),f(n-3,2),5,3]*A
=[f(n,1),f(n,2),f(n-1,1),f(n-1,2),f(n-2,1),f(n-2,2),5,3]

最后也就是这个

 [f(n,1),f(n,2),6,5,1,4,5,3]
=[6,5,1,4,2,3,5,3]*A^(n-3)
完整代码
A = [[0, 1, 1, 0, 0, 0, 0, 0],
     [1, 0, 0, 1, 0, 0, 0, 0],
     [0, 0, 0, 0, 1, 0, 0, 0],
     [0, 0, 0, 0, 0, 1, 0, 0],
     [2, 3, 0, 0, 0, 0, 0, 0],
     [0, 2, 0, 0, 0, 0, 0, 0],
     [1, 0, 0, 0, 0, 0, 1, 0],
     [0, 1, 0, 0, 0, 0, 0, 1]]
S = [6, 5, 1, 4, 2, 3, 5, 3]
# [f(n,1),f(n,2) 6 5 1 4 5 3]=[6 5 1 4 2 3 5 3] * A^(n-3)

# 矩阵相乘矩阵A为a*b,矩阵B为b*c;
def multi(matrix_a, matrix_b, a, b, c):
    matrix_result = [[0] * c for _ in range(a)]
    for i in range(a):
        for j in range(c):
            for k in range(b):
                matrix_result[i][j] = (matrix_result[i][j] + (matrix_a[i][k] * matrix_b[k][j]) % 99999999) % 99999999
    return matrix_result
    
# 单位矩阵
E = [[0] * 8 for _ in range(8)]
for i in range(8):
    E[i][i] = 1

n = int(input())
if n == 1:
    print('2')
    print('3')
if n == 2:
    print('1')
    print('4')
if n == 3:
    print('6')
    print('5')
if n >= 4:
	# 快速幂
    n = n - 3
    while n:
        if n & 1:
            E = multi(E, A, 8, 8, 8)
        A = multi(A,A,8,8,8)
        n = n >> 1
        
    sum1 = sum2 = 0
    for i in range(8):
        sum1 = (sum1 + (S[i] * E[i][0]) % 99999999) % 99999999
        sum2 = (sum2 + (S[i] * E[i][1]) % 99999999) % 99999999
    print(sum1)
    print(sum2)

举报

相关推荐

0 条评论