Maximum items that can be filled in K Knapsacks of given Capacity

Given an integer array W[] consisting of weights of items and ‘K’ knapsacks of capacity ‘C’, find maximum weight we can put in the knapsacks if breaking of an item is not allowed.

Examples:

Input : w[] = {3, 9, 8}, k = 1, c = 11
Output : 11
The required subset will be {3, 8}
where 3+8 = 11

Input : w[] = {3, 9, 8}, k = 1, c = 10
Output : 9

We will use Dynamic programming to solve this problem.
We will use two variables to represent the states of DP.

  1. ‘i’ – The current index we are working on.
  2. ‘R’ – It contains the remaining capacity of each and every knapsack.

Now, how will a single variable store the remaining capacity of every knapsack?

For that, we will initialise ‘R’ as R = C + C*(C+1) + C*(C+1)^2 + C*(C+1)^3 ..+ C*(C+1)^(k-1)
This initialises all the ‘k’ knapsacks with capacity ‘C’.

Now, we need to perform two queries:

  • Reading remaining space of jth knapsack: (r/(c+1)^(j-1))%(c+1).
  • Decreasing remaining space of jth knapsack by x: set r = r – x*(c+1)^(j-1).

Now, at each step, we will have k+1 choices.

  1. Reject index ‘i’.
  2. Put item ‘i’ in knapsack 1.
  3. Put item ‘i’ in knapsack 2.
  4. Put item ‘i’ in knapsack 3.

  5. k+1) Put item ‘i’ in knapsack k.

We will choose the path that maximizes the result.

Below is the implementation of above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

#include <bits/stdc++.h>
using namespace std;
  
// 2-d array to store states of DP
vector<vector<int> > dp;
  
// 2-d array to store if a state
// has been solved
vector<vector<bool> > v;
  
// Vector to store power of variable 'C'.
vector<int> exp_c;
  
// function to compute the states
int FindMax(int i, int r, int w[],
            int n, int c, int k)
{
  
    // Base case
    if (i >= n)
        return 0;
  
    // Checking if a state has been solved
    if (v[i][r])
        return dp[i][r];
  
    // Setting a state as solved
    v[i][r] = 1;
    dp[i][r] = FindMax(i + 1, r, w, n, c, k);
  
    // Recurrence relation
    for (int j = 0; j < k; j++) {
        int x = (r / exp_c[j]) % (c + 1);
        if (x - w[i] >= 0)
            dp[i][r] = max(dp[i][r], w[i] + 
            FindMax(i + 1, r - w[i] * exp_c[j], w, n, c, k));
    }
  
    // Returning the solved state
    return dp[i][r];
}
  
// Function to initialize global variables
// and find the initial value of 'R'
int PreCompute(int n, int c, int k)
{
  
    // Resizing the variables
    exp_c.resize(k);
    exp_c[0] = 1;
  
    for (int i = 1; i < k; i++){
        exp_c[i] = (exp_c[i - 1] * (c + 1));
    }
    dp.resize(n);
    for (int i = 0; i < n; i++){
        dp[i].resize(exp_c[k - 1] * (c + 1), 0);
    }
    v.resize(n);
    for (int i = 0; i < n; i++){
        v[i].resize(exp_c[k - 1] * (c + 1), 0);
    }
  
    // Variable to store the initial value of R
    int R = 0;
    for (int i = 0; i < k; i++){
        R += exp_c[i] * c;
    }
    return R;
}
  
// Driver Code
int main()
{
    // Input array
    int w[] = { 3, 8, 9 };
  
    // number of knapsacks and capacity
    int k = 1, c = 11;
  
    int n = sizeof(w) / sizeof(int);
  
    // Performing required pre-computation
    int r = PreCompute(n, c, k);
  
    // finding the required answer
    cout << FindMax(0, r, w, n, c, k);
  
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the above approach
  
# 2-d array to store states of DP
x = 100
dp = [[0 for i in range(x)] 
         for i in range(x)]
  
# 2-d array to store if a state
# has been solved
v = [[0 for i in range(x)]  
        for i in range(x)]
  
# Vector to store power of variable 'C'.
exp_c = []
  
# function to compute the states
def FindMax(i, r, w, n, c, k):
  
    # Base case
    if (i >= n):
        return 0
  
    # Checking if a state has been solved
    if (v[i][r]):
        return dp[i][r]
  
    # Setting a state as solved
    v[i][r] = 1
    dp[i][r] = FindMax(i + 1, r, w, n, c, k)
  
    # Recurrence relation
    for j in range(k):
        x = (r // exp_c[j]) % (c + 1)
        if (x - w[i] >= 0):
            dp[i][r] = max(dp[i][r], w[i] +
            FindMax(i + 1, r - w[i] * exp_c[j],
                                   w, n, c, k))
  
    # Returning the solved state
    return dp[i][r]
  
# Function to initialize global variables
# and find the initial value of 'R'
def PreCompute(n, c, k):
  
  
    # Resizing the variables
    exp_c.append(1)
  
    for i in range(1, k):
        exp_c[i] = (exp_c[i - 1] * (c + 1))
  
    # Variable to store the initial value of R
    R = 0
    for i in range(k):
        R += exp_c[i] * c
  
    return R
  
# Driver Code
  
# Input array
w =[3, 8, 9]
  
# number of knapsacks and capacity
k = 1
c = 11
  
n = len(w)
  
# Performing required pre-computation
r = PreCompute(n, c, k)
  
# finding the required answer
print(FindMax(0, r, w, n, c, k))
  
# This code is contributed by Mohit Kumar

chevron_right


Output:

11

Time complexity : O(N*k*C^k).



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 : mohit kumar 29