Weekly Contest 73 leetcode 790. Domino and Tromino Tiling

257 篇文章 17 订阅

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].
这道题很明显是一道 DP 题。因此关键在于找到 DP 的递归公式。

方法是找规律。

序列如下: 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));
	}
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值