题目:
有两种形状的瓷砖:一种是 2 x 1
的多米诺形,另一种是形如 "L" 的托米诺形。两种形状都可以旋转。
给定整数 n ,返回可以平铺 2 x n
的面板的方法的数量。返回对 109 + 7
取模 的值。
平铺指的是每个正方形都必须有瓷砖覆盖。两个平铺不同,当且仅当面板上有四个方向上的相邻单元中的两个,使得恰好有一个平铺有一个瓷砖占据两个正方形。
示例:
输入: n = 3 输出: 5 解释: 五种不同的方法如上所示。
输入: n = 1 输出: 1
代码:
class Solution:
def numTilings(self, n: int) -> int:
MOD = 10 ** 9 + 7
def multiply(a: List[List[int]], b: List[List[int]]) -> List[List[int]]:
rows, columns, temp = len(a), len(b[0]), len(b)
c = [[0] * columns for _ in range(rows)]
for i in range(rows):
for j in range(columns):
for k in range(temp):
c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % MOD
return c
def matrixPow(mat: List[List[int]], n: int) -> List[List[int]]:
ret = [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
]
while n:
if n & 1:
ret = multiply(ret, mat)
n >>= 1
mat = multiply(mat, mat)
return ret
mat = [
[0, 0, 0, 1],
[1, 0, 1, 0],
[1, 1, 0, 0],
[1, 1, 1, 1],
]
res = matrixPow(mat, n)
return res[3][3]