Skip to content
Related Articles

Related Articles

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)
 

My Personal Notes arrow_drop_up
Recommended Articles
Page :