📜  0-1背包查询

📅  最后修改于: 2021-05-07 04:48:17             🧑  作者: Mango

给定一个由项目权重组成的整数数组W []和一些由背包容量C组成的查询,对于每个查询,我们都可以将最大重量放入背包中。 C的值不超过某个整数C_MAX

例子:

建议您先尝试使用0-1背包阅读本文,然后再尝试解决此问题。

天真的方法:对于每个查询,我们都可以生成所有可能的权重子集,然后在适合背包的所有那些子集中选择权重最大的子集。因此,回答每个查询将花费指数时间。

高效的方法:我们将使用动态编程来优化对每个查询的回答。
使用2-D DP解决0-1背包问题,一种状态为“ i”作为当前索引(即选择或拒绝),另一种状态为剩余容量“ R”。
递归关系为

我们将为O(C_MAX * i)中1到C_MAX之间的’C’的每个可能值预先计算2-d数组dp [i] [C]。
使用此预计算,我们可以在O(1)时间内回答每个查询。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
#define C_MAX 30
#define max_arr_len 10
using namespace std;
  
// To store states of DP
int dp[max_arr_len][C_MAX + 1];
  
// To check if a state has
// been solved
bool v[max_arr_len][C_MAX + 1];
  
// Function to compute the states
int findMax(int i, int r, int w[], int n)
{
  
    // Base case
    if (r < 0)
        return INT_MIN;
    if (i == n)
        return 0;
  
    // Check 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] = max(w[i] + findMax(i + 1, r - w[i], w, n),
                   findMax(i + 1, r, w, n));
  
    // Returning the solved state
    return dp[i][r];
}
  
// Function to pre-compute the states
// dp[0][0], dp[0][1], .., dp[0][C_MAX]
void preCompute(int w[], int n)
{
    for (int i = C_MAX; i >= 0; i--)
        findMax(0, i, w, n);
}
  
// Function to answer a query in O(1)
int ansQuery(int w)
{
    return dp[0][w];
}
  
// Driver code
int main()
{
    int w[] = { 3, 8, 9 };
    int n = sizeof(w) / sizeof(int);
  
    // Performing required
    // pre-computation
    preCompute(w, n);
  
    int queries[] = { 11, 10, 4 };
    int q = sizeof(queries) / sizeof(queries[0]);
  
    // Perform queries
    for (int i = 0; i < q; i++)
        cout << ansQuery(queries[i]) << endl;
  
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
    static int C_MAX = 30;
    static int max_arr_len = 10;
      
    // To store states of DP
    static int dp [][] = new int [max_arr_len][C_MAX + 1];
      
    // To check if a state has
    // been solved
    static boolean v[][]= new boolean [max_arr_len][C_MAX + 1];
      
    // Function to compute the states
    static int findMax(int i, int r, int w[], int n)
    {
      
        // Base case
        if (r < 0)
            return Integer.MIN_VALUE;
        if (i == n)
            return 0;
      
        // Check if a state has
        // been solved
        if (v[i][r])
            return dp[i][r];
      
        // Setting a state as solved
        v[i][r] = true;
        dp[i][r] = Math.max(w[i] + findMax(i + 1, r - w[i], w, n),
                                        findMax(i + 1, r, w, n));
      
        // Returning the solved state
        return dp[i][r];
    }
      
    // Function to pre-compute the states
    // dp[0][0], dp[0][1], .., dp[0][C_MAX]
    static void preCompute(int w[], int n)
    {
        for (int i = C_MAX; i >= 0; i--)
            findMax(0, i, w, n);
    }
      
    // Function to answer a query in O(1)
    static int ansQuery(int w)
    {
        return dp[0][w];
    }
      
    // Driver code
    public static void main (String[] args) 
    {
  
        int w[] = new int []{ 3, 8, 9 };
        int n = w.length;
          
        // Performing required
        // pre-computation
        preCompute(w, n);
      
        int queries[] = new int [] { 11, 10, 4 };
        int q = queries.length;
      
        // Perform queries
        for (int i = 0; i < q; i++)
            System.out.println(ansQuery(queries[i]));
    }
}
  
// This code is contributed by ihritik


Python3
# Python3 implementation of the approach 
  
import numpy as np
import sys
  
C_MAX = 30
max_arr_len = 10
  
# To store states of DP 
dp = np.zeros((max_arr_len,C_MAX + 1)); 
  
# To check if a state has 
# been solved 
v = np.zeros((max_arr_len,C_MAX + 1)); 
  
INT_MIN = -(sys.maxsize) + 1
  
# Function to compute the states 
def findMax(i, r, w, n) : 
  
    # Base case 
    if (r < 0) :
        return INT_MIN; 
          
    if (i == n) :
        return 0; 
  
    # Check 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] = max(w[i] + findMax(i + 1, r - w[i], w, n), 
                findMax(i + 1, r, w, n)); 
  
    # Returning the solved state 
    return dp[i][r]; 
  
  
# Function to pre-compute the states 
# dp[0][0], dp[0][1], .., dp[0][C_MAX] 
def preCompute(w, n) : 
  
    for i in range(C_MAX, -1, -1) :
        findMax(0, i, w, n); 
  
  
# Function to answer a query in O(1) 
def ansQuery(w) : 
  
    return dp[0][w]; 
  
  
# Driver code 
if __name__ == "__main__" : 
  
    w = [ 3, 8, 9 ]; 
    n = len(w) 
  
    # Performing required 
    # pre-computation 
    preCompute(w, n); 
  
    queries = [ 11, 10, 4 ]; 
    q = len(queries)
  
    # Perform queries 
    for i in range(q) :
        print(ansQuery(queries[i]));
  
  
# This code is coontributed by AnkitRai01


C#
// C# implementation of the approach
using System;
  
class GFG
{
    static int  C_MAX = 30;
    static int  max_arr_len = 10;
      
    // To store states of DP
    static int [ , ] dp  = new int [max_arr_len, C_MAX + 1];
      
    // To check if a state has
    // been solved
    static bool [ , ] v  = new bool [max_arr_len, C_MAX + 1];
      
    // Function to compute the states
   static int findMax(int i, int r, int [] w, int n)
    {
      
        // Base case
        if (r < 0)
            return Int32.MinValue;
        if (i == n)
            return 0;
      
        // Check if a state has
        // been solved
        if (v[i, r])
            return dp[i, r];
      
        // Setting a state as solved
        v[i, r] = true;
        dp[i, r] = Math.Max(w[i] + findMax(i + 1, r - w[i], w, n),
                    findMax(i + 1, r, w, n));
      
        // Returning the solved state
        return dp[i, r];
    }
      
    // Function to pre-compute the states
    // dp[0][0], dp[0][1], .., dp[0][C_MAX]
    static void preCompute(int []w, int n)
    {
        for (int i = C_MAX; i >= 0; i--)
            findMax(0, i, w, n);
    }
      
    // Function to answer a query in O(1)
    static  int ansQuery(int w)
    {
        return dp[0, w];
    }
      
    // Driver code
    public static void Main () 
    {
  
        int []w = new int []{ 3, 8, 9 };
        int n = w.Length;
          
        // Performing required
        // pre-computation
        preCompute(w, n);
      
        int [] queries = new int [] { 11, 10, 4 };
        int q = queries.Length;
      
        // Perform queries
        for (int i = 0; i < q; i++)
            Console.WriteLine (ansQuery(queries[i]));
      
      
    }
}
  
// This code is contributed by ihritik


输出:
11
9
3