📜  在0/1背包中打印项目

📅  最后修改于: 2021-04-23 21:14:15             🧑  作者: Mango

给定n个物料的权重和值,将这些物料放在容量为W的背包中,以在背包中获得最大的总价值。换句话说,给定两个整数数组val [0..n-1]和wt [0..n-1],它们分别表示与n个项目相关联的值和权重。还要给定代表背包容量的整数W,找出物品,使给定子集的那些物品的权重之和小于或等于W。选择它(0-1属性)。

先决条件: 0/1背包

例子 :

Input : val[] = {60, 100, 120};
        wt[] = {10, 20, 30};
        W = 50;
Output : 220 //maximum value that can be obtained
         30 20 //weights 20 and 30 are included. 

Input : val[] = {40, 100, 50, 60};
        wt[] = {20, 10, 40, 30};
        W = 60;
Output : 200
         30 20 10

方法 :
令val [] = {1,4,5,7},wt [] = {1,3,4,5}
W = 7。
2d背包表如下所示:
2D背包表

从K [n] [W]开始回溯。此处K [n] [W]为9。

由于此值来自顶部(由灰色箭头显示),因此不包括此行中的项目。在桌子上垂直向上走,但不包括在背包中。现在,该值K [n-1] [W]为9并不是从顶部开始的,这意味着该行中的项目已被包含并垂直向上移动,然后由所包含项目的权重向左移动(如黑色所示)箭)。继续进行此过程,将背包中的权重3和权重4总计为9。

C++
// CPP code for Dynamic Programming based 
// solution for 0-1 Knapsack problem
#include 
  
// A utility function that returns maximum of two integers
int max(int a, int b) { return (a > b) ? a : b; }
  
// Prints the items which are put in a knapsack of capacity W
void printknapSack(int W, int wt[], int val[], int n)
{
    int i, w;
    int K[n + 1][W + 1];
  
    // Build table K[][] in bottom up manner
    for (i = 0; i <= n; i++) {
        for (w = 0; w <= W; w++) {
            if (i == 0 || w == 0)
                K[i][w] = 0;
            else if (wt[i - 1] <= w)
                K[i][w] = max(val[i - 1] + 
                    K[i - 1][w - wt[i - 1]], K[i - 1][w]);
            else
                K[i][w] = K[i - 1][w];
        }
    }
  
    // stores the result of Knapsack
    int res = K[n][W];    
    printf("%d\n", res);
      
    w = W;
    for (i = n; i > 0 && res > 0; i--) {
          
        // either the result comes from the top
        // (K[i-1][w]) or from (val[i-1] + K[i-1]
        // [w-wt[i-1]]) as in Knapsack table. If
        // it comes from the latter one/ it means 
        // the item is included.
        if (res == K[i - 1][w]) 
            continue;        
        else {
  
            // This item is included.
            printf("%d ", wt[i - 1]);
              
            // Since this weight is included its 
            // value is deducted
            res = res - val[i - 1];
            w = w - wt[i - 1];
        }
    }
}
  
// Driver code
int main()
{
    int val[] = { 60, 100, 120 };
    int wt[] = { 10, 20, 30 };
    int W = 50;
    int n = sizeof(val) / sizeof(val[0]);
      
    printknapSack(W, wt, val, n);
      
    return 0;
}


Java
// Java code for Dynamic Programming based
// solution for 0-1 Knapsack problem
  
class GFG {
      
    // A utility function that returns 
    // maximum of two integers
    static int max(int a, int b) 
    {
        return (a > b) ? a : b;
    }
  
    // Prints the items which are put 
    // in a knapsack of capacity W
    static void printknapSack(int W, int wt[], 
                             int val[], int n)
    {
        int i, w;
        int K[][] = new int[n + 1][W + 1];
  
        // Build table K[][] in bottom up manner
        for (i = 0; i <= n; i++) {
            for (w = 0; w <= W; w++) {
                if (i == 0 || w == 0)
                    K[i][w] = 0;
                else if (wt[i - 1] <= w)
                    K[i][w] = Math.max(val[i - 1] + 
                              K[i - 1][w - wt[i - 1]], K[i - 1][w]);
                else
                    K[i][w] = K[i - 1][w];
            }
        }
  
        // stores the result of Knapsack
        int res = K[n][W];
        System.out.println(res);
  
        w = W;
        for (i = n; i > 0 && res > 0; i--) {
  
            // either the result comes from the top
            // (K[i-1][w]) or from (val[i-1] + K[i-1]
            // [w-wt[i-1]]) as in Knapsack table. If
            // it comes from the latter one/ it means
            // the item is included.
            if (res == K[i - 1][w])
                continue;
            else {
  
                // This item is included.
                System.out.print(wt[i - 1] + " ");
  
                // Since this weight is included its
                // value is deducted
                res = res - val[i - 1];
                w = w - wt[i - 1];
            }
        }
    }
  
    // Driver code
    public static void main(String arg[])
    {
        int val[] = { 60, 100, 120 };
        int wt[] = { 10, 20, 30 };
        int W = 50;
        int n = val.length;
  
        printknapSack(W, wt, val, n);
    }
}
  
// This code is contributed by Anant Agarwal.


Python3
# Python3 code for Dynamic Programming
# based solution for 0-1 Knapsack problem
  
# Prints the items which are put in a 
# knapsack of capacity W
def printknapSack(W, wt, val, n):
    K = [[0 for w in range(W + 1)]
            for i in range(n + 1)]
              
    # Build table K[][] in bottom
    # up manner
    for i in range(n + 1):
        for w in range(W + 1):
            if i == 0 or w == 0:
                K[i][w] = 0
            elif wt[i - 1] <= w:
                K[i][w] = max(val[i - 1] 
                  + K[i - 1][w - wt[i - 1]],
                               K[i - 1][w])
            else:
                K[i][w] = K[i - 1][w]
  
    # stores the result of Knapsack
    res = K[n][W]
    print(res)
      
    w = W
    for i in range(n, 0, -1):
        if res <= 0:
            break
        # either the result comes from the
        # top (K[i-1][w]) or from (val[i-1]
        # + K[i-1] [w-wt[i-1]]) as in Knapsack
        # table. If it comes from the latter
        # one/ it means the item is included.
        if res == K[i - 1][w]:
            continue
        else:
  
            # This item is included.
            print(wt[i - 1])
              
            # Since this weight is included
            # its value is deducted
            res = res - val[i - 1]
            w = w - wt[i - 1]
  
# Driver code
val = [ 60, 100, 120 ]
wt = [ 10, 20, 30 ]
W = 50
n = len(val)
      
printknapSack(W, wt, val, n)
  
# This code is contributed by Aryan Garg.


C#
// C# code for Dynamic Programming based 
// solution for 0-1 Knapsack problem 
  
using System ;
  
class GFG { 
      
    // A utility function that returns 
    // maximum of two integers 
    static int max(int a, int b) 
    { 
        return (a > b) ? a : b; 
    } 
  
    // Prints the items which are put 
    // in a knapsack of capacity W 
    static void printknapSack(int W, int []wt, 
                            int []val, int n) 
    { 
        int i, w; 
        int [,]K = new int[n + 1,W + 1]; 
  
        // Build table K[][] in bottom up manner 
        for (i = 0; i <= n; i++) { 
            for (w = 0; w <= W; w++) { 
                if (i == 0 || w == 0) 
                    K[i,w] = 0; 
                else if (wt[i - 1] <= w) 
                    K[i,w] = Math.Max(val[i - 1] + 
                            K[i - 1,w - wt[i - 1]], K[i - 1,w]); 
                else
                    K[i,w] = K[i - 1,w]; 
            } 
        } 
  
        // stores the result of Knapsack 
        int res = K[n,W]; 
        Console.WriteLine(res); 
  
        w = W; 
        for (i = n; i > 0 && res > 0; i--) { 
  
            // either the result comes from the top 
            // (K[i-1][w]) or from (val[i-1] + K[i-1] 
            // [w-wt[i-1]]) as in Knapsack table. If 
            // it comes from the latter one/ it means 
            // the item is included. 
            if (res == K[i - 1,w]) 
                continue; 
            else { 
  
                // This item is included. 
                Console.Write(wt[i - 1] + " "); 
  
                // Since this weight is included its 
                // value is deducted 
                res = res - val[i - 1]; 
                w = w - wt[i - 1]; 
            } 
        } 
    } 
  
    // Driver code 
    public static void Main() 
    { 
        int []val = { 60, 100, 120 }; 
        int []wt = { 10, 20, 30 }; 
        int W = 50; 
        int n = val.Length; 
  
        printknapSack(W, wt, val, n); 
    } 
} 
  
// This code is contributed by Ryuga.


PHP
 0 && $res > 0; $i--) 
    {
          
        // either the result comes from the top
        // (K[i-1][w]) or from (val[i-1] + K[i-1]
        // [w-wt[i-1]]) as in Knapsack table. If
        // it comes from the latter one/ it means 
        // the item is included.
        if ($res == $K[$i - 1][$w]) 
            continue;     
        else 
        {
  
            // This item is included.
            echo $wt[$i - 1] . " ";
              
            // Since this weight is included
            // its value is deducted
            $res = $res - $val[$i - 1];
            $w = $w - $wt[$i - 1];
        }
    }
}
  
// Driver code
$val = array(60, 100, 120);
$wt = array(10, 20, 30);
$W = 50;
$n = sizeof($val);
printknapSack($W, $wt, $val, $n);
  
// This code is contributed by ita_c
?>


输出:
220
30 20