Skip to content
Related Articles

Related Articles

Improve Article
Number of ways to make exactly C components in a 2*N matrix
  • Last Updated : 17 May, 2021

Given two positive integers N and C. There is a 2*N matrix where each cell of the matrix can be colored in 0 or 1. The task is to find number of ways, the 2*N matrix is formed having exactly c components. 
 

A cell is said to be in the same component with the other cell if it shares a side with the other cell (immediate neighbor) and is of the same color.

Examples: 
 

Input: N = 2, C = 1 
Output:
Explanation: 
C = 1 can be possible when all the cells of the matrix are colored in the same color. 
We have 2 choices for coloring 0 and 1. Hence the answer is 2.
Input: N = 1, C = 2 
Output:
 

 



Approach: The idea to solve this problem is using Dynamic Programming. Construct a 4D DP matrix of (N+1) * (C+1) * 2 * 2 sizes, where N is the number of columns, C is the number of components and the 2*2 dimension is the arrangement in the last column. The last column can have four different combinations. They are 00, 01, 10, 11. 
Each cell of the matrix dp[i][j][row1][row2] gives the number of ways of having j components in i columns when arrangement in the last column is row1, row2. If current subproblem has been evaluated i.e dp[column][component][row1][row2] != -1, then use this result, else recursively compute the value. 
 

  • Base Case: When the number of columns becomes greater than N, then return 0. If the number of columns becomes equal to N then the answer depends on the number of components. If the components are equal to C then return 1 else return 0.
  • Case 1 : When previous column has the same color ({0, 0} or {1, 1}) in its row. 
    In this case, the components will increase by 1 if the current column has different values in its rows ({0, 1} or {1, 0}). The components will also increase by 1 if the current column has the opposite color but with the same value in its rows. That is the current column has {1, 1} when previous column has {0, 0}. or the current column has {0, 0} when previous column has {1, 1} . The components remain the same when the current column has the same combination as that of previous column.
  • Case 2 : When previous column has the different color ({0, 1} or {1, 0}) in its row. 
    In this case, the components will increase by 2 if the current column has entirely opposite combination as that of its previous column. That is when the current column is {1, 0} and the previous column is {0, 1}. or the current column is {0, 1} and the previous column is {1, 0} . In all other cases, components remain same.

Below is the implementation of the above approach:
 

C++




// C++ implementation to find the
// number of ways to make exactly
// C components in a 2 * N matrix
 
#include <bits/stdc++.h>
using namespace std;
 
// row1 and row2 are one
// when both are same colored
int n, k;
int dp[1024][2048][2][2];
 
// Function to find the number of
// ways to make exactly C components
// in a 2 * N matrix
int Ways(int col, int comp,
         int row1, int row2)
{
 
    // if No of components
    // at any stage exceeds
    // the given number
    // then base case
    if (comp > k)
        return 0;
 
    if (col > n) {
        if (comp == k)
            return 1;
        else
            return 0;
    }
 
    // Condition to check
    // if already visited
    if (dp[col][comp][row1][row2] != -1)
        return dp[col][comp][row1][row2];
 
    // if not visited previously
    else {
        int ans = 0;
 
        // At the first column
        if (col == 1) {
 
            // color {white, white} or
            // {black, black}
            ans
                = (ans
                   + Ways(col + 1, comp + 1, 0, 0)
                   + Ways(col + 1, comp + 1, 1, 1));
 
            // Color {white, black} or
            // {black, white}
            ans
                = (ans
                   + Ways(col + 1, comp + 2, 0, 1)
                   + Ways(col + 1, comp + 2, 1, 0));
        }
        else {
 
            // If previous both
            // rows have same color
            if ((row1 && row2)
                || (!row1 && !row2)) {
 
                // Fill with {same, same} and
                // {white, black} and {black, white}
                ans = (((ans
                         + Ways(col + 1, comp + 1, 0, 0))
                        + Ways(col + 1, comp + 1, 1, 0))
                       + Ways(col + 1, comp + 1, 0, 1));
 
                // Fill with same without
                // increase in component
                // as it has been
                // counted previously
                ans = (ans
                       + Ways(col + 1, comp, 1, 1));
            }
 
            // When previous rows
            // had {white, black}
            if (row1 && !row2) {
                ans = (((ans
                         + Ways(col + 1, comp, 0, 0))
                        + Ways(col + 1, comp, 1, 1))
                       + Ways(col + 1, comp, 1, 0));
                ans = (ans
                       + Ways(col + 1, comp + 2, 0, 1));
            }
 
            // When previous rows
            // had {black, white}
            if (!row1 && row2) {
                ans = (((ans
                         + Ways(col + 1, comp, 0, 0))
                        + Ways(col + 1, comp, 1, 1))
                       + Ways(col + 1, comp, 0, 1));
                ans = (ans
                       + Ways(col + 1, comp + 2, 1, 0));
            }
        }
 
        // Memoization
        return dp[col][comp][row1][row2] = ans;
    }
}
 
// Driver Code
signed main()
{
    n = 2;
    k = 1;
    memset(dp, -1, sizeof(dp));
 
    // Initially at first column
    // with 0 components
    cout << Ways(1, 0, 0, 0);
    return 0;
}

Java




// Java implementation to find the
// number of ways to make exactly
// C components in a 2 * N matrix
class GFG{
 
// row1 and row2 are one
// when both are same colored
static int n, k;
static int [][][][]dp = new int[1024][2048][2][2];
 
// Function to find the number of
// ways to make exactly C components
// in a 2 * N matrix
static int Ways(int col, int comp,
                int row1, int row2)
{
 
    // if No of components
    // at any stage exceeds
    // the given number
    // then base case
    if (comp > k)
        return 0;
 
    if (col > n)
    {
        if (comp == k)
            return 1;
        else
            return 0;
    }
 
    // Condition to check
    // if already visited
    if (dp[col][comp][row1][row2] != -1)
        return dp[col][comp][row1][row2];
 
    // if not visited previously
    else
    {
        int ans = 0;
 
        // At the first column
        if (col == 1)
        {
 
            // color {white, white} or
            // {black, black}
            ans = (ans + Ways(col + 1, comp + 1, 0, 0) +
                         Ways(col + 1, comp + 1, 1, 1));
 
            // Color {white, black} or
            // {black, white}
            ans = (ans + Ways(col + 1, comp + 2, 0, 1) +
                         Ways(col + 1, comp + 2, 1, 0));
        }
        else
        {
 
            // If previous both
            // rows have same color
            if ((row1 > 0 && row2 > 0) ||
                (row1 == 0 && row2 ==0))
            {
 
                // Fill with {same, same} and
                // {white, black} and {black, white}
                ans = (((ans +
                         Ways(col + 1, comp + 1, 0, 0)) +
                         Ways(col + 1, comp + 1, 1, 0)) +
                         Ways(col + 1, comp + 1, 0, 1));
 
                // Fill with same without
                // increase in component
                // as it has been
                // counted previously
                ans = (ans +
                       Ways(col + 1, comp, 1, 1));
            }
 
            // When previous rows
            // had {white, black}
            if (row1 > 0 && row2 == 0)
            {
                ans = (((ans +
                         Ways(col + 1, comp, 0, 0)) +
                         Ways(col + 1, comp, 1, 1)) +
                         Ways(col + 1, comp, 1, 0));
                ans = (ans +
                       Ways(col + 1, comp + 2, 0, 1));
            }
 
            // When previous rows
            // had {black, white}
            if (row1 ==0 && row2 > 0)
            {
                ans = (((ans +
                         Ways(col + 1, comp, 0, 0)) +
                         Ways(col + 1, comp, 1, 1)) +
                         Ways(col + 1, comp, 0, 1));
                ans = (ans +
                       Ways(col + 1, comp + 2, 1, 0));
            }
        }
 
        // Memoization
        return dp[col][comp][row1][row2] = ans;
    }
}
 
// Driver Code
public static void main(String[] args)
{
    n = 2;
    k = 1;
    for (int i = 0; i < 1024; i++)
        for (int j = 0; j < 2048; j++)
            for (int k = 0; k < 2; k++)
                for (int l = 0; l < 2; l++)
                    dp[i][j][k][l] = -1;
 
    // Initially at first column
    // with 0 components
    System.out.print(Ways(1, 0, 0, 0));
}
}
 
// This code is contributed by Rajput-Ji

C#




// C# implementation to find the
// number of ways to make exactly
// C components in a 2 * N matrix
using System;
 
class GFG{
 
// row1 and row2 are one
// when both are same colored
static int n, k;
static int [,,,]dp = new int[ 1024, 2048, 2, 2 ];
 
// Function to find the number of
// ways to make exactly C components
// in a 2 * N matrix
static int Ways(int col, int comp,
                int row1, int row2)
{
     
    // If No of components
    // at any stage exceeds
    // the given number
    // then base case
    if (comp > k)
        return 0;
 
    if (col > n)
    {
        if (comp == k)
            return 1;
        else
            return 0;
    }
 
    // Condition to check
    // if already visited
    if (dp[ col, comp, row1, row2 ] != -1)
        return dp[ col, comp, row1, row2 ];
 
    // If not visited previously
    else
    {
        int ans = 0;
 
        // At the first column
        if (col == 1)
        {
 
            // color {white, white} or
            // {black, black}
            ans = (ans + Ways(col + 1, comp + 1, 0, 0) +
                         Ways(col + 1, comp + 1, 1, 1));
 
            // Color {white, black} or
            // {black, white}
            ans = (ans + Ways(col + 1, comp + 2, 0, 1) +
                         Ways(col + 1, comp + 2, 1, 0));
        }
        else
        {
             
            // If previous both
            // rows have same color
            if ((row1 > 0 && row2 > 0) ||
                (row1 == 0 && row2 == 0))
            {
                 
                // Fill with {same, same} and
                // {white, black} and {black, white}
                ans = (((ans +
                         Ways(col + 1, comp + 1, 0, 0)) +
                         Ways(col + 1, comp + 1, 1, 0)) +
                         Ways(col + 1, comp + 1, 0, 1));
 
                // Fill with same without
                // increase in component
                // as it has been
                // counted previously
                ans = (ans +
                       Ways(col + 1, comp, 1, 1));
            }
 
            // When previous rows
            // had {white, black}
            if (row1 > 0 && row2 == 0)
            {
                ans = (((ans +
                         Ways(col + 1, comp, 0, 0)) +
                         Ways(col + 1, comp, 1, 1)) +
                         Ways(col + 1, comp, 1, 0));
                ans = (ans +
                       Ways(col + 1, comp + 2, 0, 1));
            }
 
            // When previous rows
            // had {black, white}
            if (row1 == 0 && row2 > 0)
            {
                ans = (((ans +
                         Ways(col + 1, comp, 0, 0)) +
                         Ways(col + 1, comp, 1, 1)) +
                         Ways(col + 1, comp, 0, 1));
                ans = (ans +
                       Ways(col + 1, comp + 2, 1, 0));
            }
        }
 
        // Memoization
        return dp[ col, comp, row1, row2 ] = ans;
    }
}
 
// Driver Code
public static void Main(String[] args)
{
    n = 2;
    k = 1;
     
    for(int i = 0; i < 1024; i++)
       for(int j = 0; j < 2048; j++)
          for(int K = 0; K < 2; K++)
             for(int l = 0; l < 2; l++)
                dp[ i, j, K, l ] = -1;
 
    // Initially at first column
    // with 0 components
    Console.Write(Ways(1, 0, 0, 0));
}
}
 
// This code is contributed by Rajput-Ji
Output: 
2

 

Time Compexity: O(N*C)
 

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 industry experts, please refer Geeks Classes Live 




My Personal Notes arrow_drop_up
Recommended Articles
Page :