版权声明:原创部分都是自己总结的,如果转载请指明出处。觉得有帮助的老铁,请双击666! https://blog.csdn.net/qq_36387683/article/details/81939513
关键词:矩阵加速线性递推公式
用1*2的矩形填充2*n的矩形,共有多少种填充方式
dp[i]=dp[i-1]+dp[i-2]—————Fibonacci数列
初始值:dp[1]=1,dp[2]=2,定义dp[0]=1,dp[-1]=0;
n很大,需要用矩阵加速运算!
观察下列式子:
其中(Fn-2) = 0, (Fn-1) = 1; (Fn-2, Fn-1)* [[0, 1],[ 1, 1]] = (Fn-1, Fn)
所以只需要计算矩阵的n次幂即可!
矩阵求幂可以用快速幂加速!
快速幂计算:https://blog.csdn.net/qq_36387683/article/details/81941556
拓展:
1.第二列的两个1改成a和b可以快速求fn=a∗fn−2+b∗fn−1 fn=a∗fn−2+b∗fn−1的通项公式
2.同理,可构造k维矩阵快速求出fn=∑n−1i=n−kai∗fi fn=∑i=n−kn−1ai∗fi的通项公式,矩阵的前k-1列每列仅保留一个1,最后一列为系数列填充aiai
复杂度:O(k^3*log(n))
class Solution:
"""
@param n: An integer
@return: An integer
"""
#时间复杂度O(logN), 利用矩阵求解
def climbStairs(self, n):
# write your code here
if n < 3:
return n
f1 = 1
f2 = 2
base = [[0, 1], [1, 1]]
'''
(f1, f2) * [ 0 1]^n-2 = (Fn-1, Fn)
[ 1 1]
'''
res = self.matrixPower(base, n-2)
# Fn = f1 * res[0][1] + f2* res[1][1]
return f1 * res[0][1] + f2 * res[1][1]
# 快速幂算法:二进制法
def matrixPower(self, m, p):
# 对于矩阵的乘法来说,ans应该初始化为单位矩阵,对于单位矩阵E,任何矩阵A * E = A
res = [[0] * len(i) for i in m]
for i in range(len(res)):
res[i][i] = 1
tmp = m
while p != 0:
if p & 1 != 0:
res = self.multiMatrix(res, tmp)
tmp = self.multiMatrix(tmp, tmp)
p = p >> 1
return res
'''
#利用二分求阶乘加速计算,只能计算小数量的幂,当幂大时,会超出递归深度
def matrixPower(self, m, p):
if p == 1:
return m
elif p == 2:
return self.multiMatrix(m, m)
else:
if p % 2 == 0:
tmp = self.matrixPower(m, p/2)
tmp = self.multiMatrix(tmp, tmp)
return tmp
else:
tmp = self.matrixPower(m, p/2)
tmp = self.multiMatrix(tmp, tmp)
#因为是奇数,不能二分,所以多乘一次
tmp = self.multiMatrix(tmp, m)
return tmp
'''
# 计算矩阵乘法的函数,m1,m2是两个矩阵
def multiMatrix(self, m1, m2):
# 定义一个临时矩阵,来存放m1*m2的结果
res = [[0] * len(m2[0]) for _ in m1]
for i in range(len(m1)):
for j in range(len(m2[0])):
for k in range(len(m2)):
res[i][j] += m1[i][k] * m2[k][j]
return res