You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
You have two types of tiles: a 2 x 1 domino shape and a tromino shape. You may rotate these shapes.
Given an integer n, return the number of ways to tile an2 x nboard. Since the answer may be very large, return it modulo109 + 7.
In a tiling, every square must be covered by a tile. Two tilings are different if and only if there are two 4-directionally adjacent cells on the board such that exactly one of the tilings has both squares occupied by a tile.
Example 1:
**Input:** n = 3
**Output:** 5
**Explanation:** The five different ways are show above.
You have two types of tiles: a
2 x 1
domino shape and a tromino shape. You may rotate these shapes.Given an integer n, return the number of ways to tile an
2 x n
board. Since the answer may be very large, return it modulo109 + 7
.In a tiling, every square must be covered by a tile. Two tilings are different if and only if there are two 4-directionally adjacent cells on the board such that exactly one of the tilings has both squares occupied by a tile.
Example 1:
Example 2:
Constraints:
1 <= n <= 1000
这道题是关于多米诺骨牌和三格骨牌的,其中由两个方形格子组成的是多米诺骨牌(音译,即为双格骨牌),而由三个方形格子组成的‘L’型的是三格骨牌,但其实本质还是个拼格子的问题,并没有利用到骨牌酷炫的连倒技能,倒反而更像是俄罗斯方块中的形状。说是有一个2xN大小的棋盘,我们需要用这些多米诺和三格骨牌来将棋盘填满,问有多少种不同的填充方法,结果需要对一个超大数取余。那么根据博主多年的经验,对于这种求极值,并且超大的情况下,只能使用动态规划 Dynamic Programming 来做,什么暴力递归神马的,等着爆栈吧。
既然决定了要用 DP 来做,那么首先就来设计 dp 数组吧,这里就用一个一维的 dp 数组就行了,其中 dp[i] 表示填满前i列的不同填法总数对超大数 10e^9+7 取余后的结果。DP 解法的难点就是求状态转移方程了,没什么太好的思路的时候,就从最简单的情况开始罗列吧。题目中给了N的范围是 [1, 1000],那么来看:
当 N=1 时,那么就是一个 2x1 大小的棋盘,只能放一个多米诺骨牌,只有一种情况。
当 N=2 时,那么就是一个 2x2 大小的棋盘,如下图所示,有两种放置方法,可以将两个多米诺骨牌竖着并排放,或者是将其横着并排放。
当 N=3 时,那么就是一个 3x2 大小的棋盘,共用五种放置方法,如下图所示。仔细观察这五种情况,可以发现其时时跟上面的情况有联系的。前两种情况其实是 N=2 的两种情况后面加上了一个竖着的多米诺骨牌,第三种情况其实是 N=1 的那种情况后面加上了两个平行的横向的多米诺骨牌,后两种情况是 N=0(空集)再加上两种三格骨牌对角摆开的情况。
当 N=4 时,那么就是一个 4x2 大小的棋盘,共用十一种放置方法,太多了就不一一画出来了,但是其也是由之前的情况组合而成的。首先是 N=3 的所有情况后面加上一个竖着多米诺骨牌,然后是 N=2 的所有情况加上两个平行的横向的多米诺骨牌,然后 N=1 再加上两种三格骨牌对角摆开的情况,然后 N=0(空集)再加上两种三格骨牌和一个横向多米诺骨牌组成的情况。
N=5 的情况博主没有再画了,可以参见ZhengKaiWei大神的帖子中的手稿图,很萌~
根据目前的状况,我们可以总结一个很重要的规律,就是 dp[n] 是由之前的 dp 值组成的,其中 dp[n-1] 和 dp[n-2] 各自能贡献一种组成方式,而 dp[n-3],一直到 dp[0],都能各自贡献两种组成方式,所以状态转移方程呼之欲出:
dp[n] = dp[n-1] + dp[n-2] + 2 * (dp[n-3] + ... + dp[0])
= dp[n-1] + dp[n-3] + dp[n-2] + dp[n-3] + 2 * (dp[n-4] + ... dp[0])
= dp[n-1] + dp[n-3] + dp[n-1]
= 2 * dp[n-1] + dp[n-3]
最后化简后的形式就是最终的状态转移方程了,是不是叼的飞起~
Github 同步地址:
#790
参考资料:
https://leetcode.com/problems/domino-and-tromino-tiling/
https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116513/Java-solution-DP
https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116581/Detail-and-explanation-of-O(n)-solution-why-dpn2*dn-1+dpn-3
https://leetcode.com/problems/domino-and-tromino-tiling/discuss/116664/Schematic-explanation-of-two-equivalent-DP-recurrence-formula
LeetCode All in One 题目讲解汇总(持续更新中...)
(欢迎加入博主的知识星球,博主将及时答疑解惑,并分享刷题经验与总结,快快加入吧~)
喜欢请点赞,疼爱请打赏❤️~.~
微信打赏
|
Venmo 打赏
---|---
The text was updated successfully, but these errors were encountered: