Leetcode 790. 多米诺和托米诺平铺 C++

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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

你可能感兴趣的:(Leetcode 790. 多米诺和托米诺平铺 C++)