We have two types of tiles(地砖): a 2x1 domino shape, and an "L" tromino shape. These shapes may be rotated.
XX <- domino XX <- "L" tromino X
Given N, how many ways are there to tile a 2 x N board? Return your answer modulo 10^9 + 7.
Example: Input: 3 Output: 5 Explanation: The five different ways are listed below, different letters indicates different tiles: XYZ XXZ XYY XXY XYY XYZ YYZ XZZ XYY XXY
Note:
- N will be in range
[1, 1000]
.
方法是找规律。
序列如下: 1, 1, 2, 5, 11, 24, 53, 117, 258, 569, 1255
我们发现:
5 = 2 * 2 + 1
11 = 5 * 2 + 1
24 = 11 * 2 + 2
53 = 24 * 2 + 5
117 = 57 * 2 + 11
A[N] = A[N-1] * 2 + A[N-3]
使用DP的思路来考虑,为什么会出现这个公式呢?
A[N] can be get from A[N-1] by simply add
X
X
to the right of A[N-1],
A[N] can be get from A[N-2] by simply add
XX
YY
to the right of A[N-2] , Note that the method must be unique from those from A[N-1], thus the following tilling is not allowed:
XY
XY
cause it will be replicate to the cases from A[N-1] to A[N]
How about A[N-3] and all previous cases? There are always 2 unique ways to turn them into A[N] (add the following blocks to the right of A[N-i]):
1.
XXY (from A[N-3])
XYY
XXYY (from A[N-4])
XZZY
XXZZY (from A[N-5])
XZZYY
XXZZYY (from A[N-6])
XZZZZY
etc…
2. vertically flip case 1(垂直反转case1)
Thus:
A[N] = A[N-1] + A[N-2] + 2 * sum(A[0:N-2])
重点在于:We can find dp[n-1] and dp[n-2] have one way to translate to dp[n], and dp[n-3] ... dp[0] have two ways to translate to dp[n]. 然后就是推导公式,化简过程。
package leetcode;
public class Domino_and_Tromino_Tiling_790 {
public int numTilings(int N) {
int mod=1000000007;
long[] dp=new long[1001];
dp[1]=1;
dp[2]=2;
dp[3]=5;
for(int i=4;i<=N;++i){
dp[i]=2*dp[i-1]+dp[i-3];
dp[i]=dp[i]%mod;
}
return (int)dp[N];
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Domino_and_Tromino_Tiling_790 d=new Domino_and_Tromino_Tiling_790();
System.out.println(d.numTilings(30));
}
}