Open In App

A Space Optimized DP solution for 0-1 Knapsack Problem

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Given the weights and values of n items, put these items in a knapsack of capacity W to get the maximum total value in the knapsack. In other words, given two integer arrays val[0..n-1] and wt[0..n-1] which represent values and weights associated with n items respectively. Also given an integer W which represents knapsack capacity, find out the maximum value subset of val[] such that sum of the weights of this subset is smaller than or equal to W. We cannot break an item, either pick the complete item or don’t pick it (0-1 property).
Here W <= 2000000 and n <= 500 

Examples: 

Input: W = 10, n = 3
        val[] = {7, 8, 4}
        wt[] = {3, 8, 6}
Output: 11
Explanation: We get maximum value by picking items of 3 KG and 6 KG.

We have discussed a Dynamic Programming based solution here. In the previous solution, we used a n * W matrix. We can reduce the used extra space. The idea behind the optimization is, to compute mat[i][j], we only need solution of previous row. In 0-1 Knapsack Problem if we are currently on mat[i][j] and we include ith element then we move j-wt[i] steps back in previous row and if we exclude the current element we move on jth column in the previous row. So here we can observe that at a time we are working only with 2 consecutive rows. 

In the below solution, we create a matrix of size 2*W. If n is odd, then the final answer will be at mat[0][W] and if n is even then the final answer will be at mat[1][W] because index starts from 0. 

C++




// C++ program of a space optimized DP solution for
// 0-1 knapsack problem.
#include<bits/stdc++.h>
using namespace std;
 
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// mat[2][W+1] to store final result
int KnapSack(int val[], int wt[], int n, int W)
{
    // matrix to store final result
    int mat[2][W+1];
    memset(mat, 0, sizeof(mat));
 
    // iterate through all items
    int i = 0;
    while (i < n) // one by one traverse each element
    {
        int j = 0; // traverse all weights j <= W
 
        // if i is odd that mean till now we have odd
        // number of elements so we store result in 1th
        // indexed row
        if (i%2!=0)
        {
            while (++j <= W) // check for each value
            {
                if (wt[i] <= j) // include element
                    mat[1][j] = max(val[i] + mat[0][j-wt[i]],
                                    mat[0][j] );
                else           // exclude element
                    mat[1][j] = mat[0][j];
            }
 
        }
 
        // if i is even that mean till now we have even number
        // of elements so we store result in 0th indexed row
        else
        {
            while(++j <= W)
            {
                if (wt[i] <= j)
                    mat[0][j] = max(val[i] + mat[1][j-wt[i]],
                                     mat[1][j]);
                else
                    mat[0][j] = mat[1][j];
            }
        }
        i++;
    }
 
    // Return mat[0][W] if n is odd, else mat[1][W]
    return (n%2 != 0)? mat[0][W] : mat[1][W];
}
 
// Driver program to test the cases
int main()
{
    int val[] = {7, 8, 4}, wt[] = {3, 8, 6}, W = 10, n = 3;
    cout << KnapSack(val, wt, n, W) << endl;
    return 0;
}


Java




// Java program of a space optimized DP solution for
// 0-1 knapsack problem.
class GFG
{
     
    // val[] is for storing maximum
    // profit for each weight
    // wt[] is for storing weights
    // n number of item
    // W maximum capacity of bag
    // mat[2][W+1] to store final result
    static int KnapSack(int val[], int wt[],
                            int n, int W)
    {
        // matrix to store final result
        int mat[][] = new int[2][W + 1];
 
        // iterate through all items
        int i = 0;
        while (i < n) // one by one traverse each element
        {
            int j = 0; // traverse all weights j <= W
 
            // if i is odd that mean till now we have odd
            // number of elements so we store result in 1th
            // indexed row
            if (i % 2 != 0)
            {
                while (++j <= W) // check for each value
                {
                    if (wt[i] <= j) // include element
                    {
                        mat[1][j] = Math.max(val[i] + mat[0][j - wt[i]],
                                                      mat[0][j]);
                    } else // exclude element
                    {
                        mat[1][j] = mat[0][j];
                    }
                }
 
            }
             
            // if i is even that means till now
            // we have even number of elements
            // so we store result in 0th indexed row
            else
            {
                while (++j <= W)
                {
                    if (wt[i] <= j)
                    {
                        mat[0][j] = Math.max(val[i] + mat[1][j - wt[i]],
                                                      mat[1][j]);
                    } else
                    {
                        mat[0][j] = mat[1][j];
                    }
                }
            }
            i++;
        }
 
        // Return mat[0][W] if n is odd, else mat[1][W]
        return (n % 2 != 0) ? mat[0][W] : mat[1][W];
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int val[] = {7, 8, 4},
            wt[] = {3, 8, 6},
            W = 10, n = 3;
        System.out.println(KnapSack(val, wt, n, W));
    }
}
 
// This code is contributed by PrinciRaj1992


Python3




# Python program of a space
# optimized DP solution for
# 0-1 knapsack problem.
 
# val[] is for storing maximum
# profit for each weight
# wt[] is for storing weights
# n number of item
# W maximum capacity of bag
# mat[2][W+1] to store final result
 
def KnapSack(val, wt, n, W):
     
    # matrix to store final result
    mat = [[0 for i in range(W + 1)]
              for i in range(2)]
    # iterate through all items
    i = 0
    while i < n: # one by one traverse
                 # each element
        j = 0 # traverse all weights j <= W
         
        # if i is odd that mean till
        # now we have odd number of
        # elements so we store result 
        # in 1th indexed row
        if i % 2 == 0:
            while j < W: # check for each value
                j += 1
                if wt[i] <= j: # include element
                    mat[1][j] = max(val[i] + mat[0][j -
                                     wt[i]], mat[0][j])
                else: # exclude element
                    mat[1][j] = mat[0][j]
                     
        # if i is even that mean till
        # now we have even number
        # of elements so we store
        # result in 0th indexed row
        else:
            while j < W:
                j += 1
                if wt[i] <= j:
                    mat[0][j] = max(val[i] + mat[1][j -
                                     wt[i]], mat[1][j])
                else:
                    mat[0][j] = mat[1][j]
        i += 1
    # Return mat[0][W] if n is
    # odd, else mat[1][W]
    if n % 2 == 0:
        return mat[0][W]
    else:
        return mat[1][W]
 
# Driver code
val = [7, 8, 4]
wt = [3, 8, 6]
W = 10
n = 3
print(KnapSack(val, wt, n, W))
 
# This code is contributed
# by sahilshelangia


C#




// C# program of a space optimized DP solution for
// 0-1 knapsack problem.
using System;
     
class GFG
{
     
    // val[] is for storing maximum
    // profit for each weight
    // wt[] is for storing weights
    // n number of item
    // W maximum capacity of bag
    // mat[2,W+1] to store final result
    static int KnapSack(int []val, int []wt,
                            int n, int W)
    {
        // matrix to store final result
        int [,]mat = new int[2, W + 1];
 
        // iterate through all items
        int i = 0;
        while (i < n) // one by one traverse each element
        {
            int j = 0; // traverse all weights j <= W
 
            // if i is odd that mean till now we have odd
            // number of elements so we store result in 1th
            // indexed row
            if (i % 2 != 0)
            {
                while (++j <= W) // check for each value
                {
                    if (wt[i] <= j) // include element
                    {
                        mat[1, j] = Math.Max(val[i] + mat[0, j - wt[i]],
                                                      mat[0, j]);
                    } else // exclude element
                    {
                        mat[1,j] = mat[0,j];
                    }
                }
 
            }
             
            // if i is even that means till now
            // we have even number of elements
            // so we store result in 0th indexed row
            else
            {
                while (++j <= W)
                {
                    if (wt[i] <= j)
                    {
                        mat[0, j] = Math.Max(val[i] + mat[1, j - wt[i]],
                                                      mat[1, j]);
                    }
                    else
                    {
                        mat[0, j] = mat[1, j];
                    }
                }
            }
            i++;
        }
 
        // Return mat[0,W] if n is odd, else mat[1,W]
        return (n % 2 != 0) ? mat[0, W] : mat[1, W];
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int []val = {7, 8, 4};
        int []wt = {3, 8, 6};
        int W = 10, n = 3;
        Console.WriteLine(KnapSack(val, wt, n, W));
    }
}
 
// This code is contributed by 29AjayKumar


PHP




<?php
// PHP program of a space optimized DP
// solution for 0-1 knapsack problem.
 
// val[] is for storing maximum profit
// for each weight wt[] is for storing
// weights n number of item
// W maximum capacity of bag
// mat[2][W+1] to store final result
function KnapSack(&$val, &$wt, $n, $W)
{
    // matrix to store final result
    $mat = array_fill(0, 2,
           array_fill(0, $W + 1, NULL));
     
    // iterate through all items
    $i = 0;
    while ($i < $n) // one by one traverse
                    // each element
    {
        $j = 0; // traverse all weights j <= W
 
        // if i is odd that mean till now we
        // have odd number of elements so we
        // store result in 1th indexed row
        if ($i % 2 != 0)
        {
            while (++$j <= $W) // check for each value
            {
                if ($wt[$i] <= $j) // include element
                    $mat[1][$j] = max($val[$i] + $mat[0][$j -
                                       $wt[$i]], $mat[0][$j]);
                else         // exclude element
                    $mat[1][$j] = $mat[0][$j];
            }
 
        }
 
        // if i is even that mean till now we have
        // even number of elements so we store result
        // in 0th indexed row
        else
        {
            while(++$j <= $W)
            {
                if ($wt[$i] <= $j)
                    $mat[0][$j] = max($val[$i] + $mat[1][$j -
                                       $wt[$i]], $mat[1][$j]);
                else
                    $mat[0][$j] = $mat[1][$j];
            }
        }
        $i++;
    }
 
    // Return mat[0][W] if n is odd,
    // else mat[1][W]
    if ($n % 2 != 0)
        return $mat[0][$W];
    else
        return $mat[1][$W];
}
 
// Driver Code
$val = array(7, 8, 4);
$wt = array(3, 8, 6);
$W = 10;
$n = 3;
echo KnapSack($val, $wt, $n, $W) . "\n";
 
// This code is contributed
// by Akanksha Rai
?>


Javascript




<script>
// Javascript program of a space optimized DP solution for
// 0-1 knapsack problem.
     
    // val[] is for storing maximum
    // profit for each weight
    // wt[] is for storing weights
    // n number of item
    // W maximum capacity of bag
    // mat[2][W+1] to store final result
    function KnapSack(val, wt, n, W)
    {
     
        // matrix to store final result
        let mat = new Array(2);
        for(let i = 0; i < 2; i++)
        {
            mat[i] = new Array(W + 1);
        }
        for(let i = 0; i < 2; i++)
        {
            for(let j = 0; j < W + 1; j++)
            {
                mat[i][j] = 0;
            }
        }
         
        // iterate through all items
        let i = 0;
        while (i < n) // one by one traverse each element
        {
            let j = 0; // traverse all weights j <= W
   
            // if i is odd that mean till now we have odd
            // number of elements so we store result in 1th
            // indexed row
            if (i % 2 != 0)
            {
                while (++j <= W) // check for each value
                {
                    if (wt[i] <= j) // include element
                    {
                        mat[1][j] = Math.max(val[i] + mat[0][j - wt[i]],
                                                      mat[0][j]);
                    } else // exclude element
                    {
                        mat[1][j] = mat[0][j];
                    }
                }
   
            }
               
            // if i is even that means till now
            // we have even number of elements
            // so we store result in 0th indexed row
            else
            {
                while (++j <= W)
                {
                    if (wt[i] <= j)
                    {
                        mat[0][j] = Math.max(val[i] + mat[1][j - wt[i]],
                                                      mat[1][j]);
                    } else
                    {
                        mat[0][j] = mat[1][j];
                    }
                }
            }
            i++;
        }
   
        // Return mat[0][W] if n is odd, else mat[1][W]
        return (n % 2 != 0) ? mat[0][W] : mat[1][W];
    }
     
    let val=[7, 8, 4];
    let wt=[3, 8, 6];
    let W = 10, n = 3;
    document.write(KnapSack(val, wt, n, W));
     
    // This code is contributed by rag2127
</script>


Output

11

Time Complexity: O(n * W) 
Auxiliary Space: O(W)

Here is an optimized code contributed by Gaurav Mamgain  

C++14




// C++ program of a space optimized DP solution for
// 0-1 knapsack problem.
#include <bits/stdc++.h>
using namespace std;
 
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// dp[W+1] to store final result
int KnapSack(int val[], int wt[], int n, int W)
{
    // array to store final result
    // dp[i] stores the profit with KnapSack capacity "i"
    int dp[W + 1];
 
    // initially profit with 0 to W KnapSack capacity is 0
    memset(dp, 0, sizeof(dp));
 
    // iterate through all items
    for (int i = 0; i < n; i++)
        // traverse dp array from right to left
        for (int j = W; j >= wt[i]; j--)
            dp[j] = max(dp[j], val[i] + dp[j - wt[i]]);
    /*above line finds out maximum of  dp[j](excluding ith
      element value) and val[i] + dp[j-wt[i]] (including ith
      element value and the
      profit with "KnapSack capacity - ith element weight")
    */
    return dp[W];
}
 
// Driver program to test the cases
int main()
{
    int val[] = { 7, 8, 4 }, wt[] = { 3, 8, 6 }, W = 10,
        n = 3;
    cout << KnapSack(val, wt, n, W) << endl;
    return 0;
}
 
// This code is contributed by Gaurav Mamgain


Java




// Java program of a space optimized DP solution for
// 0-1 knapsack problem.
import java.util.Arrays;
 
class GFG
{
 
 
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// dp[W+1] to store final result
static int KnapSack(int val[], int wt[], int n, int W)
{
    // array to store final result
    //dp[i] stores the profit with KnapSack capacity "i"
    int []dp = new int[W+1];
     
    //initially profit with 0 to W KnapSack capacity is 0
    Arrays.fill(dp, 0);
 
    // iterate through all items
    for(int i=0; i < n; i++)
     
        //traverse dp array from right to left
        for(int j = W; j >= wt[i]; j--)
            dp[j] = Math.max(dp[j] , val[i] + dp[j - wt[i]]);
             
    /*above line finds out maximum of dp[j](excluding ith element value)
    and val[i] + dp[j-wt[i]] (including ith element value and the
    profit with "KnapSack capacity - ith element weight") */
    return dp[W];
}
 
// Driver code
public static void main(String[] args)
{
    int val[] = {7, 8, 4}, wt[] = {3, 8, 6}, W = 10, n = 3;
    System.out.println(KnapSack(val, wt, n, W));
}
}
 
// This code is contributed by Princi Singh


Python3




# Python program of a space optimized DP solution for
# 0-1 knapsack problem.
 
# val[] is for storing maximum profit for each weight
# wt[] is for storing weights
# n number of item
# W maximum capacity of bag
# dp[W+1] to store final result
def KnapSack(val, wt, n, W):
     
    # array to store final result
    # dp[i] stores the profit with KnapSack capacity "i"
    dp = [0]*(W+1);
 
    # iterate through all items
    for i in range(n):
         
        #traverse dp array from right to left
        for j in range(W,wt[i]-1,-1):
            dp[j] = max(dp[j] , val[i] + dp[j-wt[i]]);
             
    '''above line finds out maximum of dp[j](excluding ith element value)
    and val[i] + dp[j-wt[i]] (including ith element value and the
    profit with "KnapSack capacity - ith element weight") *'''
    return dp[W];
 
 
# Driver program to test the cases
val = [7, 8, 4];
wt = [3, 8, 6];
W = 10; n = 3;
print(KnapSack(val, wt, n, W));
 
# This code is contributed by Princi Singh


C#




// C# program of a space optimized DP solution for
// 0-1 knapsack problem.
using System;
 
class GFG
{
 
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// dp[W+1] to store final result
static int KnapSack(int []val, int []wt, int n, int W)
{
    // array to store final result
    //dp[i] stores the profit with KnapSack capacity "i"
    int []dp = new int[W + 1];
     
    //initially profit with 0 to W KnapSack capacity is 0
    for(int i = 0; i < W + 1; i++)
        dp[i] = 0;
 
    // iterate through all items
    for(int i = 0; i < n; i++)
     
        //traverse dp array from right to left
        for(int j = W; j >= wt[i]; j--)
            dp[j] = Math.Max(dp[j] , val[i] + dp[j - wt[i]]);
             
    /*above line finds out maximum of dp[j](excluding ith element value)
    and val[i] + dp[j-wt[i]] (including ith element value and the
    profit with "KnapSack capacity - ith element weight") */
    return dp[W];
}
 
// Driver code
public static void Main(String[] args)
{
    int []val = {7, 8, 4};
    int []wt = {3, 8, 6};
    int W = 10, n = 3;
    Console.WriteLine(KnapSack(val, wt, n, W));
}
}
 
// This code is contributed by Rajput-Ji


Javascript




<script>
 
// Javascript program of a space optimized DP solution for
// 0-1 knapsack problem.
     
    // val[] is for storing maximum profit for each weight
    // wt[] is for storing weights
    // n number of item
    // W maximum capacity of bag
    // dp[W+1] to store final result
    function KnapSack(val,wt,n,W)
    {
        // array to store final result
        // dp[i] stores the profit with KnapSack capacity "i"
        let dp = new Array(W+1);
          
        // initially profit with 0 to W KnapSack capacity is 0
        for(let i=0;i<W+1;i++)
        {
            dp[i]=0;
        }
      
        // iterate through all items
        for(let i=0; i < n; i++)
          
            // traverse dp array from right to left
            for(let j = W; j >= wt[i]; j--)
                dp[j] = Math.max(dp[j] , val[i] + dp[j - wt[i]]);
                  
        /*above line finds out maximum of dp[j]
        (excluding ith element value)and
        val[i] + dp[j-wt[i]] (including ith element value and the
        profit with "KnapSack capacity - ith element weight") */
        return dp[W];
    }
     
    // Driver code
     
    let val=[7, 8, 4];
    let wt=[3, 8, 6];
    let W = 10, n = 3;
    document.write(KnapSack(val, wt, n, W));
     
    // This code is contributed by avanitrachhadiya2155
     
</script>


Output

11

Time complexity: O(n * W)
Auxiliary space: O(W)

This article is reviewed by team geeksforgeeks. 

 



Last Updated : 24 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads