 Open in App
Not now

# Count ways to select N pairs of candies of distinct colors (Dynamic Programming + Bitmasking)

• Difficulty Level : Medium
• Last Updated : 08 Mar, 2023

Given an integer N representing the number of red and blue candies and a matrix mat[][] of size N * N, where mat[i][j] = 1 represents the existence of a pair between ith red candy and jth blue candy, the task is to find the count of ways to select N pairs of candies such that each pair contains distinct candies of different colors.

Examples:

Input: N = 2, mat[][] = { { 1, 1 }, { 1, 1 } }
Output:
Explanation:
Possible ways to select N (= 2) pairs of candies are { { (1, 1), (2, 2) }, { (1, 2), (2, 1) } }.
Therefore, the required output is 2.

Input: N = 3, mat[][] = { { 0, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 } }
Output:
Explanation:
Possible ways to select N (= 3) pairs of candies are: { { (1, 2), (2, 1), (3, 3) }, { (1, 2), (2, 3), (3, 1) }, { (1, 3), (2, 1), (3, 2) } }
Therefore, the required output is 2.

Naive Approach: The simplest approach to solve this problem is to generate all possible permutations of N pairs containing distinct candies of different colors. Finally, print the count obtained.

Below is the implementation of the above approach:

## C++14

 `// C++14 program to implement``// the above approach``#include ``using` `namespace` `std;` `// Function to count ways to select N distinct``// pairs of candies with different colours``int` `numOfWays(vector> a, ``int` `n,``                 ``int` `i, set<``int``> &blue)``{``    ` `    ``// If n pairs are selected``    ``if` `(i == n)``        ``return` `1;` `    ``// Stores count of ways``    ``// to select the i-th pair``    ``int` `count = 0;` `    ``// Iterate over the range [0, n]``    ``for``(``int` `j = 0; j < n; j++)``    ``{``        ` `        ``// If pair (i, j) is not included``        ``if` `(a[i][j] == 1 && blue.find(j) == blue.end())``        ``{``            ``blue.insert(j);``            ``count += numOfWays(a, n, i + 1, blue);``            ``blue.erase(j);``        ``}``    ``}``    ``return` `count;``}` `// Driver Code``int` `main()``{``    ``int` `n = 3;``    ``vector> mat = { { 0, 1, 1 },``                                ``{ 1, 0, 1 },``                                ``{ 1, 1, 1 } };``    ``set<``int``> mpp;``    ` `    ``cout << (numOfWays(mat, n, 0, mpp));``}` `// This code is contributed by mohit kumar 29`

## Java

 `// Java program to implement``// the above approach``import` `java.io.*;``import` `java.lang.*;``import` `java.util.*;` `class` `GFG{` `// Function to count ways to select N distinct``// pairs of candies with different colours``static` `int` `numOfWays(``int` `a[][], ``int` `n, ``int` `i,``                     ``HashSet blue)``{``    ` `    ``// If n pairs are selected``    ``if` `(i == n)``        ``return` `1``;` `    ``// Stores count of ways``    ``// to select the i-th pair``    ``int` `count = ``0``;` `    ``// Iterate over the range [0, n]``    ``for``(``int` `j = ``0``; j < n; j++)``    ``{``        ` `        ``// If pair (i, j) is not included``        ``if` `(a[i][j] == ``1` `&& !blue.contains(j))``        ``{``            ``blue.add(j);``            ``count += numOfWays(a, n, i + ``1``, blue);``            ``blue.remove(j);``        ``}``    ``}``    ``return` `count;``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ``int` `n = ``3``;``    ``int` `mat[][] = { { ``0``, ``1``, ``1` `},``                    ``{ ``1``, ``0``, ``1` `},``                    ``{ ``1``, ``1``, ``1` `} };``    ``HashSet mpp = ``new` `HashSet<>();` `    ``System.out.println((numOfWays(mat, n, ``0``, mpp)));``}``}` `// This code is contributed by Kingash`

## Python3

 `# Python3 program to implement``# the above approach`  `# Function to count ways to select N distinct``# pairs of candies with different colours``def` `numOfWays(a, n, i ``=` `0``, blue ``=` `[]):` `    ``# If n pairs are selected``    ``if` `i ``=``=` `n:``        ``return` `1` `    ``# Stores count of ways``    ``# to select the i-th pair``    ``count ``=` `0` `    ``# Iterate over the range [0, n]``    ``for` `j ``in` `range``(n):` `        ``# If pair (i, j) is not included``        ``if` `mat[i][j] ``=``=` `1` `and` `j ``not` `in` `blue:``            ``count ``+``=` `numOfWays(mat, n, i ``+` `1``,``                                ``blue ``+` `[j])``                                ` `    ``return` `count` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:``    ``n ``=` `3``    ``mat ``=` `[ [``0``, ``1``, ``1``],``            ``[``1``, ``0``, ``1``],``            ``[``1``, ``1``, ``1``] ]``    ``print``(numOfWays(mat, n))`

## C#

 `// C# program to implement``// the above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG{``    ` `// Function to count ways to select N distinct``// pairs of candies with different colours``static` `int` `numOfWays(``int``[,] a, ``int` `n, ``int` `i,``                     ``HashSet<``int``> blue)``{``    ` `    ``// If n pairs are selected``    ``if` `(i == n)``        ``return` `1;` `    ``// Stores count of ways``    ``// to select the i-th pair``    ``int` `count = 0;` `    ``// Iterate over the range [0, n]``    ``for``(``int` `j = 0; j < n; j++)``    ``{``        ` `        ``// If pair (i, j) is not included``        ``if` `(a[i, j] == 1 && !blue.Contains(j))``        ``{``            ``blue.Add(j);``            ``count += numOfWays(a, n, i + 1, blue);``            ``blue.Remove(j);``        ``}``    ``}``    ``return` `count;``}` `// Driver Code``public` `static` `void` `Main()``{``    ``int` `n = 3;``    ``int``[,] mat = { { 0, 1, 1 },``                   ``{ 1, 0, 1 },``                   ``{ 1, 1, 1 } };``    ``HashSet<``int``> mpp = ``new` `HashSet<``int``>();` `    ``Console.WriteLine((numOfWays(mat, n, 0, mpp)));``}``}` `// This code is contributed by ukasp`

## Javascript

 ``

Output:

`3`

Time complexity: O(N!)
Auxiliary Space: O(N) where N is recursion stack space

Efficient Approach: The above approach can be optimized for Dynamic programming with Bit masking. Instead of generating all permutations of N blue candies, for every red candy, use a mask, where jth bit of mask checks if jth blue candy is available for selecting the current pair or not.
The recurrence relation to solving the problem is as follows:

If Kth bit of mask is unset and mat[i][k] = 1:
dp[i + 1][j | (1 << k)] += dp[i][j]

where, (j | (1 << k)) marks the kth blue candy as selected.
dp[i][j] = Count of ways to make pairs between i red candy and N blue candies, where j is a permutation of N bit number ranging from 0 to 2N – 1).

Follow the steps below to solve the problem:

• Initialize a 2D array, say dp[][], where dp[i][j] stores the count of ways to make pairs between i red candies and N blue candies. j represents a permutation of N bit number ranging from 0 to 2N-1.
• Use the above recurrence relation and fill all possible dp states of the recurrence relation.
• Finally, print the dp state where there are N red candies and N blue candies are selected, i.e. dp[i][2n-1].

Below is the implementation of the above approach:

## C++

 `// C++ code to implement the approach` `#include ``#include ``using` `namespace` `std;` `// Function to count ways to select N distinct``// pairs of candies with different colors``int` `numOfWays(``int` `a[], ``int` `n)``{``  ` `    ``// dp[i][j]: Stores count of ways to make``    ``// pairs between i red candies and N blue candies``    ``int` `dp[1 << n];` `    ``memset``(dp, 0, ``sizeof``(dp));` `    ``// If there is no red and blue candy,``    ``// the count of ways to make n pairs is 1``    ``dp = 1;` `    ``// i: Stores count of red candy``    ``for` `(``int` `i = 0; i < n; i++) {` `        ``// j generates a permutation of blue``        ``// candy of selected / not selected``        ``// as a binary number with n bits``        ``for` `(``int` `j = 0; j < (1 << n); j++) {` `            ``if` `(dp[i][j] == 0) {``                ``continue``;``            ``}` `            ``// Iterate over the range [0, n]``            ``for` `(``int` `k = 0; k < n; k++) {` `                ``// Create a mask with only``                ``// the k-th bit as set``                ``int` `mask = (1 << k);` `                ``// If Kth bit of mask is``                ``// unset and mat[i][k] = 1``                ``if` `((mask & j) == 0 && a[i][k] == 1) {``                    ``dp[i + 1][j | mask] += dp[i][j];``                ``}``            ``}``        ``}``    ``}` `    ``// Return the dp states, where n red``    ``// and n blue candies are selected``    ``return` `dp[n][(1 << n) - 1];``}` `int` `main()``{``    ``int` `n = 3;``    ``int` `mat = {``    ``{0, 1, 1},``    ``{1, 0, 1},``    ``{1, 1, 1}``    ``};``    ``cout<

## Java

 `import` `java.util.Arrays;` `public` `class` `Main {` `  ``// Function to count ways to select N distinct``  ``// pairs of candies with different colors``  ``static` `int` `numOfWays(``int``[][] a, ``int` `n) {` `    ``// dp[i][j]: Stores count of ways to make``    ``// pairs between i red candies and N blue candies``    ``int``[][] dp = ``new` `int``[n + ``1``][``1` `<< n + ``1``];` `    ``// If there is no red and blue candy,``    ``// the count of ways to make n pairs is 1``    ``dp[``0``][``0``] = ``1``;` `    ``// i: Stores count of red candy``    ``for` `(``int` `i = ``0``; i < n; i++) {` `      ``// j generates a permutation of blue``      ``// candy of selected / not selected``      ``// as a binary number with n bits``      ``for` `(``int` `j = ``0``; j < (``1` `<< n); j++) {` `        ``if` `(dp[i][j] == ``0``) {``          ``continue``;``        ``}` `        ``// Iterate over the range [0, n]``        ``for` `(``int` `k = ``0``; k < n; k++) {` `          ``// Create a mask with only``          ``// the k-th bit as set``          ``int` `mask = (``1` `<< k);` `          ``// If Kth bit of mask is``          ``// unset and mat[i][k] = 1``          ``if` `((mask & j) == ``0` `&& a[i][k] == ``1``) {``            ``dp[i + ``1``][j | mask] += dp[i][j];``          ``}``        ``}``      ``}``    ``}` `    ``// Return the dp states, where n red``    ``// and n blue candies are selected``    ``return` `dp[n][(``1` `<< n) - ``1``];``  ``}` `  ``public` `static` `void` `main(String[] args) {``    ``int` `n = ``3``;``    ``int``[][] mat = ``new` `int``[][] {``      ``{``0``, ``1``, ``1``},``      ``{``1``, ``0``, ``1``},``      ``{``1``, ``1``, ``1``}``    ``};``    ``System.out.println(numOfWays(mat, n));``  ``}``}` `// This code is contributed by phasing17.`

## Python3

 `# Python program to implement``# the above approach`` ` ` ` `# Function to count ways to select N distinct``# pairs of candies with different colors``def` `numOfWays(a, n):`  `    ``# dp[i][j]: Stores count of ways to make``    ``# pairs between i red candies and N blue candies``    ``dp ``=` `[[``0``]``*``((``1` `<< n)``+``1``) ``for` `_ ``in` `range``(n ``+` `1``)]` `    ``# If there is no red and blue candy,``    ``# the count of ways to make n pairs is 1``    ``dp[``0``][``0``] ``=` `1` `    ``# i: Stores count of red candy``    ``for` `i ``in` `range``(n):` `        ``# j generates a permutation of blue``        ``# candy of selected / not selected``        ``# as a binary number with n bits``        ``for` `j ``in` `range``(``1` `<< n):` `            ``if` `dp[i][j] ``=``=` `0``:``                ``continue``   ` `            ``# Iterate over the range [0, n]   ``            ``for` `k ``in` `range``(n):` `                ``# Create a mask with only``                ``# the k-th bit as set``                ``mask ``=` `1` `<< k``                ` `                ``# If Kth bit of mask is``                ``# unset  and mat[i][k] = 1``                ``if` `not``(mask & j) ``and` `a[i][k]:``                    ``dp[i ``+` `1``][j | mask] ``+``=` `dp[i][j]``                    ` `        ` `                    ` `    ``# Return the dp states, where n red``    ``# and n blue candies are selected``    ``return` `dp[n][(``1` `<< n)``-``1``]`   `# Driver Code``if` `__name__ ``=``=` `"__main__"``:``    ``n ``=` `3``    ``mat ``=` `[[``0``, ``1``, ``1``],``           ``[``1``, ``0``, ``1``],``           ``[``1``, ``1``, ``1``]]``    ``print``(numOfWays(mat, n))`

## C#

 `// C# program to implement above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG``{` `  ``// Function to count ways to select N distinct``  ``// pairs of candies with different colors``  ``static` `int` `numOfWays(``int``[][] a,``int` `n){`  `    ``// dp[i][j]: Stores count of ways to make``    ``// pairs between i red candies and N blue candies``    ``int``[][] dp = ``new` `int``[n+1][];``    ``for``(``int` `i = 0 ; i <= n ; i++){``      ``dp[i] = ``new` `int``[(1 << n)+1];``    ``}` `    ``// If there is no red and blue candy,``    ``// the count of ways to make n pairs is 1``    ``dp = 1;` `    ``// i: Stores count of red candy``    ``for``(``int` `i = 0 ; i < n ; i++){` `      ``// j generates a permutation of blue``      ``// candy of selected / not selected``      ``// as a binary number with n bits``      ``for``(``int` `j = 0 ; j < (1 << n) ; j++){` `        ``if` `(dp[i][j] == 0){``          ``continue``;``        ``}` `        ``// Iterate over the range [0, n]``        ``for` `(``int` `k = 0 ; k < n ; k++){` `          ``// Create a mask with only``          ``// the k-th bit as set``          ``int` `mask = (1 << k);` `          ``// If Kth bit of mask is``          ``// unset and mat[i][k] = 1``          ``if` `((mask & j) == 0 && a[i][k] == 1){``            ``dp[i + 1][j | mask] += dp[i][j];``          ``}``        ``}``      ``}``    ``}` `    ``// Return the dp states, where n red``    ``// and n blue candies are selected``    ``return` `dp[n][(1 << n)-1];``  ``}` `  ``// Driver Code``  ``public` `static` `void` `Main(``string``[] args){` `    ``int` `n = 3;``    ``int``[][] mat = ``new` `int``[];``    ``mat = ``new` `int``[]{0, 1, 1};``    ``mat = ``new` `int``[]{1, 0, 1};``    ``mat = ``new` `int``[]{1, 1, 1};``    ``Console.Write(numOfWays(mat, n));` `  ``}``}` `// This code is contributed by subhamgoyal2014.`

## Javascript

 `function` `numOfWays(a, n) {` `    ``// dp[i][j]: Stores count of ways to make``    ``// pairs between i red candies and N blue candies``    ``let dp = Array.from({ length: n + 1 },``        ``() => Array.from({ length: (1 << n) + 1 }, () => 0));` `    ``// If there is no red and blue candy,``    ``// the count of ways to make n pairs is 1``    ``dp = 1;` `    ``// i: Stores count of red candy``    ``for` `(let i = 0; i < n; i++) {` `        ``// j generates a permutation of blue``        ``// candy of selected / not selected``        ``// as a binary number with n bits``        ``for` `(let j = 0; j < (1 << n); j++) {` `            ``if` `(dp[i][j] === 0) ``continue``;` `            ``// Iterate over the range [0, n]``            ``for` `(let k = 0; k < n; k++) {` `                ``// Create a mask with only``                ``// the k-th bit as set``                ``let mask = 1 << k;` `                ``// If Kth bit of mask is``                ``// unset  and mat[i][k] = 1``                ``if` `(!(mask & j) && a[i][k]) {``                    ``dp[i + 1][j | mask] += dp[i][j];``                ``}``            ``}``        ``}``    ``}` `    ``// Return the dp states, where n red``    ``// and n blue candies are selected``    ``return` `dp[n][(1 << n) - 1];``}` `let n = 3;``let mat =  [[0, 1, 1],``           ``[1, 0, 1],``           ``[1, 1, 1]]` ` ``console.log(numOfWays(mat, n))`

Output:

`3`

Time Complexity:O(N2 * 2N)
Auxiliary Space: O(N * 2N)

My Personal Notes arrow_drop_up