Skip to content
Related Articles

Related Articles

Domino and Tromino tiling problem

Improve Article
Save Article
  • Difficulty Level : Hard
  • Last Updated : 05 Aug, 2021
Improve Article
Save Article

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)


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!