Skip to content
Related Articles
Open in App
Not now

Related Articles

Domino and Tromino tiling problem

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 30 Jan, 2023
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)

Easy Dp Algorithm Using Extra O(n) space.

C++




#include<bits/stdc++.h>
#include<iostream>
#define ll long long
ll mod=1e9+7;
using namespace std;
 
void the_solver(int n){
      vector<ll>dp(n+1,0);
      dp[0]=1;
      dp[1]=1;dp[2]=2;dp[3]=5;
      if(n<=3){
        cout<<dp[n]<<endl;
        return;
      }
      for(int i=4;i<=n;i++){
          dp[i]=2*(dp[i-1])+dp[i-3];
          dp[i]%=mod;
      }
      cout<<dp[n]<<endl;
      return;
}
 
signed main(){
   int n=3;
   the_solver(n);
    return 0;
}

Java




//Java code for the above approach
import java.util.*;
 
class Main {
    static final long mod = 1000000000L + 7;
 
    // Function to solve problem
    static void theSolver(int n) {
        // Create an array of size n+1 to store the dp values
        long[] dp = new long[n + 1];
        dp[0] = 1;
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 5;
        // If n is less than or equal to 3
        if (n <= 3) {
            System.out.println(dp[n]);
            return;
        }
        // Iterate through the array
        for (int i = 4; i <= n; i++) {
            dp[i] = 2 * (dp[i - 1]) + dp[i - 3];
            dp[i] %= mod;
        }
        System.out.println(dp[n]);
        return;
    }
 
    public static void main(String[] args) {
        int n = 3;
        theSolver(n);
    }
}

Python3




mod = int(1e9+7)
 
def the_solver(n):
    dp = [0] * (n + 1)
    dp[0] = 1
    dp[1] = 1
    dp[2] = 2
    dp[3] = 5
    if n <= 3:
        print(dp[n])
        return
    for i in range(4, n + 1):
        dp[i] = 2 * dp[i - 1] + dp[i - 3]
        dp[i] %= mod
    print(dp[n])
    return
 
n = 3
the_solver(n)
 
# This codez is contributed by lokeshpotta20.

Javascript




function the_solver(n)
{
    let dp=new Array(n).fill(0);
    dp[0]=1;
    dp[1]=1;
    dp[2]=2;
    dp[3]=5;
    if(n<=3)
    {
        document.write(dp[n]);
        return;
    }
    for(let i=4;i<=n;i++){
        dp[i]=2*(dp[i-1])+dp[i-3];
        dp[i]%=mod;
    }
    document.write(dp[n]);
    return;
}
 
   let n=3;
   the_solver(n);

C#




using System;
using System.Linq;
using System.Collections.Generic;
 
class GFG
{
    static int mod=1000000007;
 
    static void the_solver(int n)
    {
        int[] dp=new int[n+1];
        for(int i=0; i<n+1; i++)
            dp[i]=0;
             
        dp[0]=1;
        dp[1]=1;
        dp[2]=2;
        dp[3]=5;
        if(n<=3){
            Console.WriteLine(dp[n]);
            return;
        }
        for(int i=4;i<=n;i++)
        {
          dp[i]=2*(dp[i-1])+dp[i-3];
          dp[i]%=mod;
        }
        Console.WriteLine(dp[n]);
        return;
    }
 
    static public void Main()
    
        int n=3;
        the_solver(n);
    }   
}

Output

5

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


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!