Given an array ‘arr’ containing the weight of ‘N’ distinct items, and two knapsacks that can withstand ‘W1’ and ‘W2’ weights, the task is to find the sum of the largest subset of the array ‘arr’, that can be fit in the two knapsacks. It’s not allowed to break any items in two, i.e an item should be put in one of the bags as a whole.
Examples: 
 
Input : arr[] = {8, 3, 2}
W1 = 10, W2 = 3
Output : 13
First and third objects go in the first knapsack. The second object goes in the second knapsack. Thus, the total weight becomes 13.
Input : arr[] = {8, 5, 3}
W1 = 10, W2 = 3
Output : 11
Solution: 
A recursive solution is to try out all the possible ways of filling the two knapsacks and choose the one giving the maximum weight. 
To optimize the above idea, we need to determine the states of DP, that we will build up our solution upon. After little observation, we can determine that this can be represented in three states (i, w1_r, w2_r). Here ‘i’ means the index of the element we are trying to store, w1_r means the remaining space of the first knapsack, and w2_r means the remaining space of the second knapsack. Thus, the problem can be solved using a 3-dimensional dynamic-programming with a recurrence relation 
 
DP[i][w1_r][w2_r] = max( DP[i + 1][w1_r][w2_r],
arr[i] + DP[i + 1][w1_r - arr[i]][w2_r],
arr[i] + DP[i + 1][w1_r][w2_r - arr[i]])
The explanation for the above recurrence relation is as follows: 
 
For each ‘i’, we can either:
- Don’t select the item ‘i’.
- Fill the item ‘i’ in first knapsack.
- Fill the item ‘i’ in second knapsack.
Below is the implementation of the above approach:
 
C++
| // C++ implementation of the above approach#include <bits/stdc++.h>#define maxN 31#define maxW 31usingnamespacestd;// 3D array to store// states of DPintdp[maxN][maxW][maxW];// w1_r represents remaining capacity of 1st knapsack// w2_r represents remaining capacity of 2nd knapsack// i represents index of the array arr we are working onintmaxWeight(int* arr, intn, intw1_r, intw2_r, inti){    // Base case    if(i == n)        return0;    if(dp[i][w1_r][w2_r] != -1)        returndp[i][w1_r][w2_r];    // Variables to store the result of three    // parts of recurrence relation    intfill_w1 = 0, fill_w2 = 0, fill_none = 0;    if(w1_r >= arr[i])        fill_w1 = arr[i] +          maxWeight(arr, n, w1_r - arr[i], w2_r, i + 1);    if(w2_r >= arr[i])        fill_w2 = arr[i] +          maxWeight(arr, n, w1_r, w2_r - arr[i], i + 1);    fill_none = maxWeight(arr, n, w1_r, w2_r, i + 1);    // Store the state in the 3D array    dp[i][w1_r][w2_r] = max(fill_none, max(fill_w1, fill_w2));    returndp[i][w1_r][w2_r];}// Driver codeintmain(){    // Input array    intarr[] = { 8, 2, 3 };    // Initializing the array with -1    memset(dp, -1, sizeof(dp));    // Number of elements in the array    intn = sizeof(arr) / sizeof(arr[0]);    // Capacity of knapsacks    intw1 = 10, w2 = 3;    // Function to be called    cout << maxWeight(arr, n, w1, w2, 0);    return0;} | 
Java
| // Java implementation of the above approachclassGFG{    staticintmaxN = 31;    staticintmaxW = 31;    // 3D array to store    // states of DP    staticintdp [][][] = newint[maxN][maxW][maxW];        // w1_r represents remaining capacity of 1st knapsack    // w2_r represents remaining capacity of 2nd knapsack    // i represents index of the array arr we are working on    staticintmaxWeight(intarr [] , intn, intw1_r, intw2_r, inti)    {        // Base case        if(i == n)            return0;        if(dp[i][w1_r][w2_r] != -1)            returndp[i][w1_r][w2_r];            // Variables to store the result of three        // parts of recurrence relation        intfill_w1 = 0, fill_w2 = 0, fill_none = 0;            if(w1_r >= arr[i])            fill_w1 = arr[i] +             maxWeight(arr, n, w1_r - arr[i], w2_r, i + 1);            if(w2_r >= arr[i])            fill_w2 = arr[i] +             maxWeight(arr, n, w1_r, w2_r - arr[i], i + 1);            fill_none = maxWeight(arr, n, w1_r, w2_r, i + 1);            // Store the state in the 3D array        dp[i][w1_r][w2_r] = Math.max(fill_none, Math.max(fill_w1, fill_w2));            returndp[i][w1_r][w2_r];    }        // Driver code    publicstaticvoidmain (String[] args)     {            // Input array        intarr[] = { 8, 2, 3};            // Initializing the array with -1                for(inti = 0; i < maxN ; i++)            for(intj = 0; j < maxW ; j++)                for(intk = 0; k < maxW ; k++)                        dp[i][j][k] = -1;                // Number of elements in the array        intn = arr.length;            // Capacity of knapsacks        intw1 = 10, w2 = 3;            // Function to be called        System.out.println(maxWeight(arr, n, w1, w2, 0));    }}// This code is contributed by ihritik | 
Python3
| # Python3 implementation of the above approach # w1_r represents remaining capacity of 1st knapsack # w2_r represents remaining capacity of 2nd knapsack # i represents index of the array arr we are working on defmaxWeight(arr, n, w1_r, w2_r, i):     # Base case     ifi ==n:        return0    ifdp[i][w1_r][w2_r] !=-1:         returndp[i][w1_r][w2_r]     # Variables to store the result of three     # parts of recurrence relation     fill_w1, fill_w2, fill_none =0, 0, 0    ifw1_r >=arr[i]:        fill_w1 =arr[i] +maxWeight(arr, n, w1_r -arr[i],                                              w2_r, i +1)     ifw2_r >=arr[i]:        fill_w2 =arr[i] +maxWeight(arr, n, w1_r,                                      w2_r -arr[i], i +1)     fill_none =maxWeight(arr, n, w1_r, w2_r, i +1)     # Store the state in the 3D array     dp[i][w1_r][w2_r] =max(fill_none, max(fill_w1,                                           fill_w2))     returndp[i][w1_r][w2_r] # Driver code if__name__ =="__main__":     # Input array     arr =[8, 2, 3]     maxN, maxW =31, 31        # 3D array to store     # states of DP     dp =[[[-1] *maxW] *maxW] *maxN        # Number of elements in the array     n =len(arr)     # Capacity of knapsacks     w1, w2 =10, 3    # Function to be called     print(maxWeight(arr, n, w1, w2, 0))     # This code is contributed by Rituraj Jain | 
C#
| // C# implementation of the above approachusingSystem;classGFG{    staticintmaxN = 31;    staticintmaxW = 31;    // 3D array to store    // states of DP    staticint[ , , ] dp = newint[maxN, maxW, maxW];        // w1_r represents remaining capacity of 1st knapsack    // w2_r represents remaining capacity of 2nd knapsack    // i represents index of the array arr we are working on    staticintmaxWeight(int[] arr, intn, intw1_r,                                    intw2_r, inti)    {        // Base case        if(i == n)            return0;        if(dp[i ,w1_r, w2_r] != -1)            returndp[i, w1_r, w2_r];            // Variables to store the result of three        // parts of recurrence relation        intfill_w1 = 0, fill_w2 = 0, fill_none = 0;            if(w1_r >= arr[i])            fill_w1 = arr[i] +             maxWeight(arr, n, w1_r - arr[i], w2_r, i + 1);            if(w2_r >= arr[i])            fill_w2 = arr[i] +             maxWeight(arr, n, w1_r, w2_r - arr[i], i + 1);            fill_none = maxWeight(arr, n, w1_r, w2_r, i + 1);            // Store the state in the 3D array        dp[i, w1_r, w2_r] = Math.Max(fill_none, Math.Max(fill_w1, fill_w2));            returndp[i, w1_r, w2_r];    }        // Driver code    publicstaticvoidMain ()     {            // Input array        int[] arr = { 8, 2, 3 };            // Initializing the array with -1                for(inti = 0; i < maxN ; i++)            for(intj = 0; j < maxW ; j++)                for(intk = 0; k < maxW ; k++)                        dp[i, j, k] = -1;                // Number of elements in the array        intn = arr.Length;            // Capacity of knapsacks        intw1 = 10, w2 = 3;            // Function to be called        Console.WriteLine(maxWeight(arr, n, w1, w2, 0));    }}// This code is contributed by ihritik | 
Javascript
| <script>// Javascript implementation of // the above approachvarmaxN = 31varmaxW = 31// 3D array to store// states of DPvardp = Array(maxN);for(vari=0;i<maxN;i++){    dp[i] = Array(maxW);    for(varj =0; j<maxW; j++)    {        dp[i][j] = Array(maxW).fill(-1);    }}// w1_r represents remaining// capacity of 1st knapsack// w2_r represents remaining// capacity of 2nd knapsack// i represents index of the array arr// we are working onfunctionmaxWeight(arr, n, w1_r, w2_r, i){    // Base case    if(i == n)        return0;    if(dp[i][w1_r][w2_r] != -1)        returndp[i][w1_r][w2_r];    // Variables to store the result of three    // parts of recurrence relation    varfill_w1 = 0, fill_w2 = 0, fill_none = 0;    if(w1_r >= arr[i])        fill_w1 = arr[i] +          maxWeight(arr, n, w1_r - arr[i],         w2_r, i + 1);    if(w2_r >= arr[i])        fill_w2 = arr[i] +          maxWeight(arr, n, w1_r, w2_r -         arr[i], i + 1);    fill_none = maxWeight(arr, n, w1_r,     w2_r, i + 1);    // Store the state in the 3D array    dp[i][w1_r][w2_r] = Math.max(fill_none,     Math.max(fill_w1, fill_w2));    returndp[i][w1_r][w2_r];}// Driver code// Input arrayvararr = [8, 2, 3 ];// Number of elements in the arrayvarn = arr.length;// Capacity of knapsacksvarw1 = 10, w2 = 3;// Function to be calleddocument.write( maxWeight(arr, n, w1, w2, 0));</script> | 
13
Time complexity: O(N*W1*W2)
Auxiliary Space: O(N*W1*W2))
Efficient approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.
Steps to solve this problem :
- Create a 3-D DP to store the solution of the subproblems.
- Initialize the DP with base cases if (i == 0) then dp[i][w1_r][w2_r] = 0
- Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP
- Return the final solution stored in return dp[n][w1][w2].
Implementation :
C++
| // C++ implementation of the tabulation approach#include <bits/stdc++.h>#define maxN 31#define maxW 31usingnamespacestd;// 3D array to store// states of DPintdp[maxN][maxW][maxW];// Function to calculate// maximum weight that can be put// into the knapsacksintmaxWeight(int* arr, intn, intw1, intw2){    // Iterate over all possible states    for(inti = 0; i <= n; i++)    {        for(intw1_r = 0; w1_r <= w1; w1_r++)        {            for(intw2_r = 0; w2_r <= w2; w2_r++)            {            // Base case                if(i == 0)            dp[i][w1_r][w2_r] = 0;            // If the current item can be put in            // the first knapsack            elseif(arr[i - 1] <= w1_r && arr[i - 1] <= w2_r)                dp[i][w1_r][w2_r] =                max(arr[i - 1] + dp[i - 1][w1_r - arr[i - 1]][w2_r],                     max(arr[i - 1] + dp[i - 1][w1_r][w2_r - arr[i - 1]],                        dp[i - 1][w1_r][w2_r]));            // If the current item can be put in            // the second knapsack            elseif(arr[i - 1] <= w2_r)                dp[i][w1_r][w2_r] = max(arr[i - 1] + dp[i - 1][w1_r][w2_r - arr[i - 1]],                                     dp[i - 1][w1_r][w2_r]);            // If the current item can be put in            // the first knapsack            elseif(arr[i - 1] <= w1_r)                dp[i][w1_r][w2_r] = max(arr[i - 1] + dp[i - 1][w1_r - arr[i - 1]][w2_r],                                     dp[i - 1][w1_r][w2_r]);            // If the current item can not be put in            // either of the knapsacks            else                dp[i][w1_r][w2_r] = dp[i - 1][w1_r][w2_r];            }        }    }        // Return the maximum weight that can be put    // into the knapsacks    returndp[n][w1][w2];}// Driver codeintmain(){    // Input array    intarr[] = { 8, 2, 3 };    // Number of elements in the array    intn = sizeof(arr) / sizeof(arr[0]);        // Capacity of knapsacks    intw1 = 10, w2 = 3;        // Function to be called    cout << maxWeight(arr, n, w1, w2);    return0;} | 
Java
| importjava.util.*;publicclassMain {      // 3D array to store states of DP    staticint[][][] dp = newint[31][31][31];    // Function to calculate maximum weight   // that can be put into the knapsacks    publicstaticintmaxWeight(int[] arr, intn,                                 intw1, intw2)    {              // Iterate over all possible states        for(inti = 0; i <= n; i++) {            for(intw1_r = 0; w1_r <= w1; w1_r++) {                for(intw2_r = 0; w2_r <= w2; w2_r++) {                    // Base case                    if(i == 0) {                        dp[i][w1_r][w2_r] = 0;                    }                                      // If the current item can be put in the first knapsack                    elseif(arr[i - 1] <= w1_r && arr[i - 1] <= w2_r) {                        dp[i][w1_r][w2_r] = Math.max(                                arr[i - 1] + dp[i - 1][w1_r - arr[i - 1]][w2_r],                                Math.max(arr[i - 1] + dp[i - 1][w1_r][w2_r - arr[i - 1]], dp[i - 1][w1_r][w2_r]));                    }                                      // If the current item can be put in the second knapsack                    elseif(arr[i - 1] <= w2_r) {                        dp[i][w1_r][w2_r] = Math.max(arr[i - 1] + dp[i - 1][w1_r][w2_r - arr[i - 1]],                                dp[i - 1][w1_r][w2_r]);                    }                                      // If the current item can be put in the first knapsack                    elseif(arr[i - 1] <= w1_r) {                        dp[i][w1_r][w2_r] = Math.max(arr[i - 1] + dp[i - 1][w1_r - arr[i - 1]][w2_r],                                dp[i - 1][w1_r][w2_r]);                    }                                      // If the current item can not be put in either of the knapsacks                    else{                        dp[i][w1_r][w2_r] = dp[i - 1][w1_r][w2_r];                    }                }            }        }        // Return the maximum weight that can be put into the knapsacks        returndp[n][w1][w2];    }    // Driver code    publicstaticvoidmain(String[] args)    {              // Input array        int[] arr = { 8, 2, 3};              // Number of elements in the array        intn = arr.length;        // Capacity of knapsacks        intw1 = 10, w2 = 3;        // Function to be called        System.out.println(maxWeight(arr, n, w1, w2));    }} | 
Python3
| # Constants for maximum valuesmaxN =31maxW =31# 3D array to store states of DPdp =[[[0for_ inrange(maxW)] for_ inrange(maxW)] for_ inrange(maxN)]# Function to calculate maximum weight that can be put into the knapsacksdefmaxWeight(arr, n, w1, w2):    # Iterate over all possible states    fori inrange(n +1):        forw1_r inrange(w1 +1):            forw2_r inrange(w2 +1):                # Base case                ifi ==0:                    dp[i][w1_r][w2_r] =0                # If the current item can be put in both knapsacks                elifarr[i -1] <=w1_r andarr[i -1] <=w2_r:                    dp[i][w1_r][w2_r] =max(                        arr[i -1] +dp[i -1][w1_r -arr[i -1]][w2_r],                        max(                            arr[i -1] +dp[i -1][w1_r][w2_r -arr[i -1]],                            dp[i -1][w1_r][w2_r]                        )                    )                # If the current item can be put in the second knapsack                elifarr[i -1] <=w2_r:                    dp[i][w1_r][w2_r] =max(                        arr[i -1] +dp[i -1][w1_r][w2_r -arr[i -1]],                        dp[i -1][w1_r][w2_r]                    )                # If the current item can be put in the first knapsack                elifarr[i -1] <=w1_r:                    dp[i][w1_r][w2_r] =max(                        arr[i -1] +dp[i -1][w1_r -arr[i -1]][w2_r],                        dp[i -1][w1_r][w2_r]                    )                # If the current item cannot be put in either knapsack                else:                    dp[i][w1_r][w2_r] =dp[i -1][w1_r][w2_r]    # Return the maximum weight that can be put into the knapsacks    returndp[n][w1][w2]# Driver codeif__name__ =="__main__":    # Input array    arr =[8, 2, 3]    # Number of elements in the array    n =len(arr)    # Capacity of knapsacks    w1 =10    w2 =3    # Function call    print(maxWeight(arr, n, w1, w2)) | 
C#
| usingSystem;publicclassKnapsackProblem{    // Function to calculate    // maximum weight that can be put    // into the knapsacks    publicstaticintMaxWeight(int[] arr, intn, intw1, intw2)    {        // 3D array to store        // states of DP        int[,,] dp = newint[n + 1, w1 + 1, w2 + 1];        // Iterate over all possible states        for(inti = 0; i <= n; i++)        {            for(intw1_r = 0; w1_r <= w1; w1_r++)            {                for(intw2_r = 0; w2_r <= w2; w2_r++)                {                    // Base case                        if(i == 0)                        dp[i, w1_r, w2_r] = 0;                    // If the current item can be put in                    // the first knapsack                    elseif(arr[i - 1] <= w1_r && arr[i - 1] <= w2_r)                        dp[i, w1_r, w2_r] =                            Math.Max(arr[i - 1] + dp[i - 1, w1_r - arr[i - 1], w2_r],                                      Math.Max(arr[i - 1] + dp[i - 1, w1_r, w2_r - arr[i - 1]],                                              dp[i - 1, w1_r, w2_r]));                    // If the current item can be put in                    // the second knapsack                    elseif(arr[i - 1] <= w2_r)                        dp[i, w1_r, w2_r] = Math.Max(arr[i - 1] + dp[i - 1, w1_r, w2_r - arr[i - 1]],                                                       dp[i - 1, w1_r, w2_r]);                    // If the current item can be put in                    // the first knapsack                    elseif(arr[i - 1] <= w1_r)                        dp[i, w1_r, w2_r] = Math.Max(arr[i - 1] + dp[i - 1, w1_r - arr[i - 1], w2_r],                                                       dp[i - 1, w1_r, w2_r]);                    // If the current item can not be put in                    // either of the knapsacks                    else                        dp[i, w1_r, w2_r] = dp[i - 1, w1_r, w2_r];                }            }        }        // Return the maximum weight that can be put        // into the knapsacks        returndp[n, w1, w2];    }    // Driver code    publicstaticvoidMain()    {        // Input array        int[] arr = { 8, 2, 3 };        // Number of elements in the array        intn = arr.Length;        // Capacity of knapsacks        intw1 = 10, w2 = 3;        // Function to be called        Console.WriteLine(MaxWeight(arr, n, w1, w2));    }} | 
Javascript
| const maxN = 31;const maxW = 31;// 3D array to store states of DPconst dp = newArray(maxN).fill(null).map(() =>            newArray(maxW).fill(null).map(() =>            newArray(maxW).fill(0)));// Function to calculate maximum weight that can be put into the knapsacksfunctionmaxWeight(arr, n, w1, w2) {    // Iterate over all possible states    for(let i = 0; i <= n; i++) {        for(let w1_r = 0; w1_r <= w1; w1_r++) {            for(let w2_r = 0; w2_r <= w2; w2_r++) {                            // Base case                if(i === 0)                 {                    dp[i][w1_r][w2_r] = 0;                }                 elseif(arr[i - 1] <= w1_r && arr[i - 1] <= w2_r)                 {                    dp[i][w1_r][w2_r] =                        Math.max(                            arr[i - 1] + dp[i - 1][w1_r - arr[i - 1]][w2_r],                            Math.max(                                arr[i - 1] + dp[i - 1][w1_r][w2_r - arr[i - 1]],                                dp[i - 1][w1_r][w2_r]                            )                        );                }                 elseif(arr[i - 1] <= w2_r)                 {                    dp[i][w1_r][w2_r] = Math.max(                        arr[i - 1] + dp[i - 1][w1_r][w2_r - arr[i - 1]],                        dp[i - 1][w1_r][w2_r]                    );                }                 elseif(arr[i - 1] <= w1_r)                 {                    dp[i][w1_r][w2_r] = Math.max(                        arr[i - 1] + dp[i - 1][w1_r - arr[i - 1]][w2_r],                        dp[i - 1][w1_r][w2_r]                    );                }                 else                {                    dp[i][w1_r][w2_r] = dp[i - 1][w1_r][w2_r];                }            }        }    }    // Return the maximum weight that can be put into the knapsacks    returndp[n][w1][w2];}// Driver code// Input arrayconst arr = [8, 2, 3];    // Number of elements in the arrayconst n = arr.length;// Capacity of knapsacksconst w1 = 10, w2 = 3;// Function to be calledconsole.log(maxWeight(arr, n, w1, w2)); | 
13
Time complexity: O(N*W1*W2)
Auxiliary Space: O(N*W1*W2))
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!


 
                                    







