有两种形状的瓷砖:一种是 2 x 1
的多米诺形,另一种是形如 "L" 的托米诺形。两种形状都可以旋转。
给定整数 n ,返回可以平铺 2 x n
的面板的方法的数量。返回对 109 + 7
取模 的值。
平铺指的是每个正方形都必须有瓷砖覆盖。两个平铺不同,当且仅当面板上有四个方向上的相邻单元中的两个,使得恰好有一个平铺有一个瓷砖占据两个正方形。
示例 1:
输入: n = 3 输出: 5 解释: 五种不同的方法如上所示。
示例 2:
输入: n = 1 输出: 1
提示:
1 <= n <= 1000
方法一:动态规划
我们首先要读懂题意,题目实际上是让我们求铺满
瓷砖的形状有两种,分别是 2 x 1
型 和 L
型,并且两种瓷砖都可以旋转。我们将旋转后的瓷砖分别记为 1 x 2
型 和 L'
型。
我们定义
- 最后一列铺满,记为
$0$ - 最后一列只铺了上方一个瓷砖,记为
$1$ - 最后一列只铺了下方一个瓷砖,记为
$2$ - 最后一列没有铺瓷砖,记为
$3$
那么答案就是
我们考虑铺到第
当 1 x 2
型瓷砖,或者 L'
型瓷砖,或者 L'
型瓷砖,或者 2 x 1
型瓷砖。因此
当 2 x 1
型瓷砖,或者 L
型瓷砖。因此
当 2 x 1
型瓷砖,或者 L'
型瓷砖。因此
当
可以发现,状态转移方程中只涉及到前一列的状态,因此我们可以使用滚动数组优化空间复杂度。
注意,过程中的状态数值可能会很大,因此需要对
时间复杂度
class Solution:
def numTilings(self, n: int) -> int:
@cache
def dfs(i, j):
if i > n or j > n:
return 0
if i == n and j == n:
return 1
ans = 0
if i == j:
ans = dfs(i + 2, j + 2) + dfs(i + 1, j + 1) + dfs(i + 2, j + 1) + dfs(i + 1, j + 2)
elif i > j:
ans = dfs(i, j + 2) + dfs(i + 1, j + 2)
else:
ans = dfs(i + 2, j) + dfs(i + 2, j + 1)
return ans % mod
mod = 10**9 + 7
return dfs(0, 0)
class Solution:
def numTilings(self, n: int) -> int:
f = [1, 0, 0, 0]
mod = 10**9 + 7
for i in range(1, n + 1):
g = [0] * 4
g[0] = (f[0] + f[1] + f[2] + f[3]) % mod
g[1] = (f[2] + f[3]) % mod
g[2] = (f[1] + f[3]) % mod
g[3] = f[0]
f = g
return f[0]
class Solution {
public int numTilings(int n) {
long[] f = {1, 0, 0, 0};
int mod = (int) 1e9 + 7;
for (int i = 1; i <= n; ++i) {
long[] g = new long[4];
g[0] = (f[0] + f[1] + f[2] + f[3]) % mod;
g[1] = (f[2] + f[3]) % mod;
g[2] = (f[1] + f[3]) % mod;
g[3] = f[0];
f = g;
}
return (int) f[0];
}
}
class Solution {
public:
const int mod = 1e9 + 7;
int numTilings(int n) {
long f[4] = {1, 0, 0, 0};
for (int i = 1; i <= n; ++i) {
long g[4] = {0, 0, 0, 0};
g[0] = (f[0] + f[1] + f[2] + f[3]) % mod;
g[1] = (f[2] + f[3]) % mod;
g[2] = (f[1] + f[3]) % mod;
g[3] = f[0];
memcpy(f, g, sizeof(g));
}
return f[0];
}
};
func numTilings(n int) int {
f := [4]int{}
f[0] = 1
const mod int = 1e9 + 7
for i := 1; i <= n; i++ {
g := [4]int{}
g[0] = (f[0] + f[1] + f[2] + f[3]) % mod
g[1] = (f[2] + f[3]) % mod
g[2] = (f[1] + f[3]) % mod
g[3] = f[0]
f = g
}
return f[0]
}