Number of ways to make exactly C components in a 2*N matrix

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: 2
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: 2



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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 coloumn
    // with 0 components
    cout << Ways(1, 0, 0, 0);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 coloumn
    // with 0 components
    System.out.print(Ways(1, 0, 0, 0));
}
}
  
// This code is contributed by Rajput-Ji

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 coloumn
    // with 0 components
    Console.Write(Ways(1, 0, 0, 0));
}
}
  
// This code is contributed by Rajput-Ji

chevron_right


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.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : Rajput-Ji