We have n box and an array of weights, where weight of ith box is given by arr[i]. We have a container which can carry a maximum weight of w. Now we have to find minimum number of containers required to pack these N items.
Exact question link : - https://www.hackerrank.com/contests/coding-round-practice/challenges/michaels-worries
Useful Resources :- https://www.geeksforgeeks.org/bin-packing-problem-minimize-number-of-used-bins/
If the constraints are small, we can solve this problem using Dynamic programming with bitmasking. Here is a code which i wrote to implement the same. However it is giving Time limit exceeded.
Constraints:
1 <= n <= 20
1 <= w <= 10^9
0 <= arr[i] <= w
int get_minimum_parcels(int n, int w, vector<int> arr) {
//stores the weight of boxes for every possible combination
vector<int> sums(1<<n);
for(int i=0;i<(1<<n);i++){
for(int j=0;j<n;j++){
if(i & (1<<j)){
sums[i]+=arr[j];
}
}
}
// dp[i][j] denotes whether it is possible to distribute
// the boxes as mentioned in the j bitmask to i containers
vector<vector<bool> > dp(21,vector<bool> (1<<n));
// Initialising for 1 container
for(int i=0;i<(1<<n);i++){
if(sums[i]<=w){
dp[1][i]=true;
} else{
dp[1][i]=false;
}
}
// The maximum answer n is always possible,
// Thus checking from 2 to n to find the min possible answer
for(int i=2;i<=n;i++){
for(int j=1;j<(1<<n);j++){
dp[i][j] = dp[i-1][j];
// Enumerating the submasks
for(int k=j;k;k = (k-1) & j){
dp[i][j] = dp[i][j] | (sums[k]<=w && dp[i-1][j-k]);
}
}
}
for(int i=1;i<=n;i++){
if(dp[i][(1<<n)-1])
return i;
}
return n;
}
Can we optimize this solution?