Leetcode 790. 多米诺和托米诺平铺
题目
有两种形状的瓷砖:一种是 2x1 的多米诺形,另一种是形如 “L” 的托米诺形。两种形状都可以旋转。
XX <- 多米诺
XX <- "L" 托米诺
X
给定 N 的值,有多少种方法可以平铺 2 x N 的面板?返回值 mod 10^9 + 7。
(平铺指的是每个正方形都必须有瓷砖覆盖。两个平铺不同,当且仅当面板上有四个方向上的相邻单元中的两个,使得恰好有一个平铺有一个瓷砖占据两个正方形。)
示例:
输入: 3
输出: 5
解释:
下面列出了五种不同的方法,不同字母代表不同瓷砖:
XYZ XXZ XYY XXY XYY
XYZ YYZ XZZ XYY XXY
提示:
- N 的范围是 [1, 1000]
题解
动态规划
- dp[i][0]表示平铺2*i的面板的方法,其中第二维的含义如下
- 0表示当前列均填满
- 1表示当前列第1行缺个空
- 2表示当前列第2行缺个空
因此转移方程为dp[i][0] = dp[i-1][0] + dp[i-2][0] + dp[i-1][1] + dp[i-1][2],
-
dp[i-1][0]是我们可以在第i列放一个2*1多米诺,
-
dp[i-2][0]是在第i-1、i-2列放两个1*2多米诺,
-
dp[i-1][1]是放一个
** *
-
dp[i-1][2]是放一个
* **
dp[i][1] = dp[i-2][0] + dp[i-2][2]
-
dp[i-2][0],是放一个
* **
-
dp[i-2][2],是在一个行放1*2的多米诺,本来上一行缺一个就变成下一行缺一个了
dp[i][2] = dp[i-2][0] + dp[i-2][1],和上述同理
详细过程见代码
代码
int numTilings(int N) {
if(N < 2) return 1;
else if(N < 3) return 2;
int mod = pow(10,9)+7;
vector<vector<int>> dp(N+1,vector<int>(3,0));
dp[1][0] = 1;
dp[2][0] = 2;
dp[2][1] = 1;
dp[2][2] = 1;
for(int i=3; i<=N; i++){
dp[i][0] = (((dp[i-1][0] + dp[i-2][0])%mod + dp[i-1][1])%mod + dp[i-1][2])%mod;
dp[i][1] = (dp[i-2][0] + dp[i-1][2])%mod;
dp[i][2] = (dp[i-2][0] + dp[i-1][1])%mod;
}
return dp[N][0];
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/domino-and-tromino-tiling
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。