Skip to content
Related Articles

Related Articles

Improve Article

Domino and Tromino tiling problem

  • Difficulty Level : Hard
  • Last Updated : 05 Aug, 2021

Given a positive integer N, the task is to find the number of ways to fill the board of dimension 2*N with a tile of dimensions 2 × 1, 1 × 2, (also known as domino) and an ‘L‘ shaped tile(also know as tromino) show below that can be rotated by 90 degrees.

The L shape tile:

XX
X
After rotating L shape tile by 90:

XX
 X
or
X
XX

Examples:

Input: N = 3
Output: 5
Explanation:
Below is the image to illustrate all the combinations:

Input: N = 1
Output: 1



Approach: The given problem can be solved based on the following observations by:

Let’s define a 2 state, dynamic programming say dp[i, j] denoting one of the following arrangements in column index i.

  • The current column can be filled with 1, 2 × 1 dominos in state 0, if the previous column had state 0.
  • The current column can be filled with 2, 1 × 2 dominos horizontally in state 0, if the i – 2 column has state 0.
  • The current column can be filled with an ‘L‘ shaped domino in state 1 and state 2, if the previous column had state 0.
  • The current column can be filled with 1 × 2 shaped domino in state 1 if the previous column has state 2 or in state 2 if the previous column has state 1.
  • Therefore, the transition of the state can be defined as the following:
    1. dp[i][0] = (dp[i – 1][0] + dp[i – 2][0]+ dp[i – 2][1] + dp[i – 2][2]).
    2. dp[i][1] = dp[i – 1][0] + dp[i – 1][2].
    3. dp[i][2] = dp[i – 1][0] + dp[i – 1][1].

Based on the above observations, follow the steps below to solve the problem:

  • If the value of N is less than 3, then print N as the total number of ways.
  • Initialize a 2-dimensional array, say dp[][3] that stores all the states of the dp.
  • Consider the Base Case: dp[0][0] = dp[1][0] = dp[1][1] = dp[1][2] = 1.
  • Iterate over the given range [2, N] and using the variable i and perform the following transitions in the dp as:
    • dp[i][0] equals (dp[i – 1][0] + dp[i – 2][0]+ dp[i – 2][1] + dp[i – 2][2]).
    • dp[i][1] equals dp[i – 1][0] + dp[i – 1][2].
    • dp[i][2] equals dp[i – 1][0] + dp[i – 1][1].
  • After completing the above steps, print the total number of ways stored in dp[N][0].

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
 
// Function to find the total number
// of ways to tile a 2*N board using
// the given types of tile
int numTilings(int N)
{
    // If N is less than 3
    if (N < 3) {
        return N;
    }
 
    // Store all dp-states
    vector<vector<long long> > dp(
        N + 1, vector<long long>(3, 0));
 
    // Base Case
    dp[0][0] = dp[1][0] = 1;
    dp[1][1] = dp[1][2] = 1;
 
    // Traverse the range [2, N]
    for (int i = 2; i <= N; i++) {
 
        // Update the value of dp[i][0]
        dp[i][0] = (dp[i - 1][0]
                    + dp[i - 2][0]
                    + dp[i - 2][1]
                    + dp[i - 2][2])
                   % MOD;
 
        // Update the value of dp[i][1]
        dp[i][1] = (dp[i - 1][0]
                    + dp[i - 1][2])
                   % MOD;
 
        // Update the value of dp[i][2]
        dp[i][2] = (dp[i - 1][0]
                    + dp[i - 1][1])
                   % MOD;
    }
 
    // Return the number of ways as
    // the value of dp[N][0]
    return dp[N][0];
}
 
// Driver Code
int main()
{
    int N = 3;
    cout << numTilings(N);
 
    return 0;
}

Java




// Java program for the above approach
import java.util.Arrays;
 
class GFG{
 
public static long MOD = 1000000007l;
 
// Function to find the total number
// of ways to tile a 2*N board using
// the given types of tile
public static long numTilings(int N)
{
     
    // If N is less than 3
    if (N < 3)
    {
        return N;
    }
 
    // Store all dp-states
    long[][] dp = new long[N + 1][3];
 
    for(long[] row : dp)
    {
        Arrays.fill(row, 0);
    }
     
    // Base Case
    dp[0][0] = dp[1][0] = 1;
    dp[1][1] = dp[1][2] = 1;
 
    // Traverse the range [2, N]
    for(int i = 2; i <= N; i++)
    {
         
        // Update the value of dp[i][0]
        dp[i][0] = (dp[i - 1][0] + dp[i - 2][0] +
                    dp[i - 2][1] + dp[i - 2][2]) % MOD;
 
        // Update the value of dp[i][1]
        dp[i][1] = (dp[i - 1][0] + dp[i - 1][2]) % MOD;
 
        // Update the value of dp[i][2]
        dp[i][2] = (dp[i - 1][0] + dp[i - 1][1]) % MOD;
    }
 
    // Return the number of ways as
    // the value of dp[N][0]
    return dp[N][0];
}
 
// Driver Code
public static void main(String args[])
{
    int N = 3;
     
    System.out.println(numTilings(N));
}
}
 
// This code is contributed by gfgking

Python3




# Python3 program for the above approache9 + 7;
 
# Function to find the total number
# of ways to tile a 2*N board using
# the given types of tile
MOD = 1e9 + 7
 
def numTilings(N):
     
    # If N is less than 3
    if (N < 3):
        return N
 
    # Store all dp-states
    dp = [[0] * 3 for i in range(N + 1)]
 
    # Base Case
    dp[0][0] = dp[1][0] = 1
    dp[1][1] = dp[1][2] = 1
 
    # Traverse the range [2, N]
    for i in range(2, N + 1):
 
        # Update the value of dp[i][0]
        dp[i][0] = (dp[i - 1][0] +
                    dp[i - 2][0] +
                    dp[i - 2][1] +
                    dp[i - 2][2]) % MOD
 
        # Update the value of dp[i][1]
        dp[i][1] = (dp[i - 1][0] +
                    dp[i - 1][2]) % MOD
 
        # Update the value of dp[i][2]
        dp[i][2] = (dp[i - 1][0] +
                    dp[i - 1][1]) % MOD
 
    # Return the number of ways as
    # the value of dp[N][0]
    return int(dp[N][0])
 
# Driver Code
N = 3
 
print(numTilings(N))
 
# This code is contributed by gfgking

C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
static int MOD = 1000000007;
 
// Function to find the total number
// of ways to tile a 2*N board using
// the given types of tile
static int numTilings(int N)
{
    // If N is less than 3
    if (N < 3) {
        return N;
    }
 
    // Store all dp-states
    int [,]dp = new int[N+1,3];
 
    // Base Case
    dp[0,0] = dp[1,0] = 1;
    dp[1,1] = dp[1,2] = 1;
 
    // Traverse the range [2, N]
    for (int i = 2; i <= N; i++) {
 
        // Update the value of dp[i,0]
        dp[i,0] = (dp[i - 1,0]
                    + dp[i - 2,0]
                    + dp[i - 2,1]
                    + dp[i - 2,2])
                   % MOD;
 
        // Update the value of dp[i,1]
        dp[i,1] = (dp[i - 1,0]
                    + dp[i - 1,2])
                   % MOD;
 
        // Update the value of dp[i,2]
        dp[i,2] = (dp[i - 1,0]
                    + dp[i - 1,1])
                   % MOD;
    }
 
    // Return the number of ways as
    // the value of dp[N,0]
    return dp[N,0];
}
 
// Driver Code
public static void Main()
{
    int N = 3;
    Console.Write(numTilings(N));
}
}
 
// This code is contributed by SURENDRA_GANGWAR.

Javascript




<script>
 
        // JavaScript program for the above approache9 + 7;
 
        // Function to find the total number
        // of ways to tile a 2*N board using
        // the given types of tile
        const MOD = 1e9 + 7;
        function numTilings(N) {
            // If N is less than 3
            if (N < 3) {
                return N;
            }
 
            // Store all dp-states
            let dp = Array(N + 1).fill().map(() => Array(3).fill(0))
 
            // Base Case
            dp[0][0] = dp[1][0] = 1;
            dp[1][1] = dp[1][2] = 1;
 
            // Traverse the range [2, N]
            for (let i = 2; i <= N; i++) {
 
                // Update the value of dp[i][0]
                dp[i][0] = (dp[i - 1][0]
                    + dp[i - 2][0]
                    + dp[i - 2][1]
                    + dp[i - 2][2])
                    % MOD;
 
                // Update the value of dp[i][1]
                dp[i][1] = (dp[i - 1][0]
                    + dp[i - 1][2])
                    % MOD;
 
                // Update the value of dp[i][2]
                dp[i][2] = (dp[i - 1][0]
                    + dp[i - 1][1])
                    % MOD;
            }
 
            // Return the number of ways as
            // the value of dp[N][0]
            return dp[N][0];
        }
 
        // Driver Code
 
        let N = 3;
        document.write(numTilings(N));
 
 
 
// This code is contributed by Potta Lokesh
    </script>
Output: 
5

 

Time Complexity: O(N)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :