Used to solve problems that are exponential in time and memory and having low constraints.
</br></br>
Assignment Problem
</br></br>
There are N person & N tasks, each task alloted to a single person, Cost matrix given, for ith person to do the jth task. Find the min cost. </br>
f(k,mask): person 1...k-1 has been assigned a task now upto the kth person and the state of the assigned task is mask
int x = _builtin_popcount(mask);
answer(k+1,mask|(1<<i)) = min(answer(k,mask|(1<<i),ans(mask)+cost[x][i]))
or, quite simply,
chmin(dp[mask|(1<<i)],dp[mask]+c[#setbits(mask)][i]);
Find the minimum distance to travel all vertex from a given node(say 0) and get back to it
int ALL = (1<<n)-1;
int dp[n+5][ALL+5];
int tsp(int mask,int pos){
if(mask==ALL) return d[pos][0];
if(dp[pos][mask]!=-1) return dp[pos][mask];
int ans = inf;
for(city=0;city<n;city++){
if(mask&(1<<city)==0){
chmin(ans, d[pos][city]+tsp(mask|(1<<city),city));
}
}
return ans;
}
Prime Mask:
void init(){
int p[100];
mem(p,1);
vi parr;
p[0]=p[1]=0;
for(int i=2;i<100;i++){
if(!p[i]) continue;
else parr.eb(i);
for(int j=2;i*j<100;j++){
p[i*j]=0;
}
}
for(int i=0;i<sz(parr);i++)
for(int j=1;j<60;j++)
if(j%parr[i]==0) primeMask[j] |= 1<<i;
}
GCD of numbers = primeMask[i] & primeMask[j]
LCM of numbers = primeMask[i] | primeMask[j]
Divisors = Iterating over submasks
GCD Set-Cover. Eg. https://codeforces.com/problemset/problem/510/D
Say you have a number a[i]. You want to know the set cover with min cost and gcd = 1.
void submask(int m){
for(int i=m;i;i=(i-1)&m){
// to do
}
}
https://cp-algorithms.com/dynamic_programming/profile-dynamics.html
Find no of ways to fill NxM matrix with 2x1 dominoes
void calc(int x=0;int y=0;int mask,int next_mask){
if(x==n) return;
if(y>=m)
dp[x+1][next_mask] += dp[x][mask];
else{
if(mask & (1<<y))
calc(x,y+1,mask,next_mask);
else{
calc(x,y+1,mask,next_mask|(1<<y));
if(y+1<m && !(mask & (1<<(y+1)))
calc(x,y+2,mask,next_mask);
}
}
}
ll dp[n+1][1<<m];
dp[0][0] = 1;
for(int x=0;x<n;x++)
for(int mask=0;mask<(1<<m);mask++)
calc(x,0,mask,0);
cout << dp[n][0];
Weighted Subset Sum:
https://codeforces.com/problemset/problem/1552/D