Introduction

Some questions can be solved very simply by identifying a pattern being followed and using the concept of Fibonacci numbers.
Fibonacci numbers follow the following sequence:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…..
The recurrence relation for the sequence is given by

The Fibonacci pattern can be observed in nature, and it is often considered a fundamental problem of dynamic programming.
This is because instead of calculating the results, again and again, we store the results of the subproblem, which helps prevent recalculations.
For example, let N = 5.
The recursion tree for this would be:

Let us look at one such problem that is equally important from an interview perspective and primarily based on identifying the pattern.
Problem Statement:
Consider a board of size 2 * N and tiles of size “2 * 1”. You have to count the number of ways in which tiling of this board is possible. You may place the tile vertically or horizontally, as per your choice.
Let us understand the problem with the help of a few examples:
Example
- N = 4
The tiling of this board is possible in 3 different ways. Let us see how:
- All 4 bricks can be placed vertically.

- All 4 bricks can be placed horizontally.

- 2 bricks can be placed horizontally and 2 vertically.

2. N = 3
The tiling of this board is possible in 2 different ways. Let us see how:
- All 3 bricks can be placed vertically.

- 2 bricks can be placed horizontally and 1 brick vertically.

3. N = 5
The tiling of this board is possible in 3 different ways. Let us see how:
- All 5 bricks can be placed vertically.

- 4 bricks can be placed horizontally and 1 vertically in 2 different ways.

- 2 bricks can be placed horizontally and 3 vertically in 2 different ways.

Now, let us solve this Tiling problem using recursion, and then we will see how and why it can be optimized using Dynamic Programming:
Recursion
We will solve this problem using recursion. We will start to tile the board from the last column, i.e.; we will first tile the Nth column, then (N-1)th column, and so on.
There are 2 cases possible:
- If we place the tile vertically, the problem will be converted into a sub-problem of tiling a board of size 2 * (N - 1).
- If we place the tile horizontally, 2 tiles will be required to cover the Nth and (N - 1)th column, and now the problem will be converted into a sub-problem of tiling a board of size 2 * (N - 2).
Thus, if countOfWays(N) denotes the number of ways to tile a board of size 2 * N, then,

If you observe, this pattern follows the Fibonacci Sequence. Hence its implementation is also the same.
Implementation
Program
/* C++ program to count the number of ways to place 2 * 1 size tiles on a 2 * n size board using recursion.*/
#include <iostream>
using namespace std;
// Function to calculate the total number of possible ways of tiling a board.
int numOfWays(int n)
{
// Base case.
if (n == 0 || n == 1)
return n;
return numOfWays(n - 1) + numOfWays(n - 2);
}
int main()
{
int n;
// Taking user input.
cout << "Enter the value of N: ";
cin >> n;
// Calling the function to predict the output.
cout << "The total number of possible ways to place the tiles on the board are " << numOfWays(n);
return 0;
}
Input:
Enter the value of N: 5
Output:
The total number of possible ways to place the tiles on the board is 5.
Time Complexity
The time complexity of this technique is exponential and is given by O(2N), where 2 * N is the size of the board.
The function uses Recursion, and in the worst case, it makes 2 calls for every N. Thus, the time complexity is O(2N).
Space Complexity
The space complexity is O(N), where ‘N’ is the length of the board.
In any case, there will be a maximum of ‘N’ function calls that will occupy O(N) space of the recursion call stack. Hence, the space complexity is given by O(N).
Now, we will see why and how the solution can be optimized using DP.
Read More - Time Complexity of Sorting Algorithms