Bitmasking and Dynamic Programming in C++

C++Server Side ProgrammingProgramming

First, we will learn about bitmasking and dynamic programming then we will solve a problem related to it that will solve your queries related to the implementation.

Bitmask also known as mask is a sequence of N -bits that encode the subset of our collection. The element of the mask can be either set or not set (i.e. 0 or 1). This denotes the availability of the chosen element in the bitmask. For example, an element i is available in the subset if the ith bit of mask is set. For the N element set, there can be a 2N mask each corresponding to a subset.

So, for solving the problem, we will start for a mask i.e. a subset assigns it a value and then finds the values for further masks using the values of the previous mask. Using this we will finally be able to calculate the value of the main set.

To calculate the optimal solution for a mask, we will remove one element in all possible ways and compute all the values which will then contribute to the final solution.

Dynamic Programming

Dynamic programming is an optimization method in which we solve subproblem and store their solutions for usage in other overlapping subproblem.

Now, let’s see a problem which we will solve using bit masking and dynamic programming

Problem

There are 50 caps with numbers from 1 to 50. The N people have some of these caps in their collection. One day all of them wear a cap to a party. But all need to look unique so, they decided to wear different numbered caps each. We are given the n number of people and the cap numbers in their collections. Our task is to find the total number of ways in which they can wear the cap so that everyone looks unique.

In the problem, the first line contains value n i.e. the number of people. The next n lines contain their collection.

Input

3
4 45 10
25
45 10

Output

4

Explanation

All possible ways are (4, 25, 45) , (4, 25, 10), (45, 25, 10), (10, 25, 45).

The output should be in the form of 1000000007 as the number of ways can be a large number.

To solve this problem, a simple solution is to find all possible combinations of people using caps. Starting from the first set and recur the remaining sets. But this solution is not optimized.

A better solution is using Bitmasking and DP by creating a mask of size 210 for 10 persons. And a vector of caps of size 51. Then, we will recur in a number of ways.

Example

Program to show the implementation of the solution

 Live Demo

#include<bits/stdc++.h>
using namespace std;
vector<int> caps[101];
int dp[1025][101];
int allmask;
long long int uniqueCaps(int mask, int i) {
   if (mask == allmask) return 1;
   if (i > 100) return 0;
   if (dp[mask][i] != -1) return dp[mask][i];
   long long int ways = uniqueCaps(mask, i+1);
   int size = caps[i].size();
   for (int j = 0; j < size; j++) {
      if (mask & (1 << caps[i][j])) continue;
         else ways += uniqueCaps(mask | (1 << caps[i][j]), i+1);
         ways %= (1000000007);
      }
      return dp[mask][i] = ways;
   }
int main() {
   int n = 3;
   // Collection of person 1
   caps[4].push_back(0);
   caps[45].push_back(0);
   caps[10].push_back(0);
   // Collection of person 2
   caps[25].push_back(1);
   // Collection of person 3
   caps[45].push_back(2);
   caps[10].push_back(2);
   allmask = (1 << n) - 1;
   memset(dp, -1, sizeof dp);
   cout<<"The number of ways the person can wear unique cap in party is:\t"<<uniqueCaps(0, 1);
   return 0;
}

Output

The number of ways the person can wear unique cap in party is: 4
raja
Published on 05-Aug-2020 07:39:46
Advertisements