📜  给定容量的 K 个背包中最多可装入的物品

📅  最后修改于: 2021-09-22 10:35:08             🧑  作者: Mango

给定一个由物品的重量和容量为“C”的“K”个背包组成的整数数组 W[],如果不允许破坏物品,请找出我们可以放入背包的最大重量。

例子:

我们将使用动态规划来解决这个问题。
我们将使用两个变量来表示 DP 的状态。

  1. ‘i’ – 我们正在处理的当前索引。
  2. ‘R’ – 它包含每个背包的剩余容量。

现在,单个变量将如何存储每个背包的剩余容量?
为此,我们将 ‘R’ 初始化为 R = C + C*(C+1) + C*(C+1)^2 + C*(C+1)^3 ..+ C*(C+1 )^(k-1)
这将初始化所有容量为“C”的“k”背包。

现在,我们需要执行两个查询:

  • 读取第j个背包的剩余空间:(r/(c+1)^(j-1))%(c+1)。
  • 将第 j 个背包的剩余空间减少 x:设置 r = r – x*(c+1)^(j-1)。

现在,在每一步,我们将有 k+1 个选择。

  1. 拒绝索引“i”。
  2. 将物品“i”放入背包 1。
  3. 将物品“i”放入背包 2。
  4. 将物品 ‘i’ 放入背包 3。

我们将选择最大化结果的路径。

下面是上述方法的实现:

C++
#include 
using namespace std;
 
// 2-d array to store states of DP
vector > dp;
 
// 2-d array to store if a state
// has been solved
vector > v;
 
// Vector to store power of variable 'C'.
vector 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;
}


Java
/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
class GFG
{
   
    // 2-d array to store if a state
    // has been solved
    static ArrayList> v =
      new ArrayList>();
   
    // 2-d array to store states of DP
    static ArrayList> dp =
      new ArrayList>();
   
    // Vector to store power of variable 'C'.
    static ArrayList exp_c =
      new ArrayList();
   
    // function to compute the states
    static 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.get(i).get(r))
        {
            return dp.get(i).get(r);
        }
       
        // Setting a state as solved
        v.get(i).set(r, true);
        dp.get(i).set(r,FindMax(i + 1, r,
                                w, n, c, k));
       
        // Recurrence relation
        for (int j = 0; j < k; j++)
        {
            int x = (r / exp_c.get(j)) % (c + 1);
            if (x - w[i] >= 0)
            {
                dp.get(i).set(r,Math.max(dp.get(i).get(r),w[i] +
                                         FindMax(i + 1, r - w[i] *
                                                 exp_c.get(j), w, n, c, k)));     
            } 
        }
       
        // Returning the solved state
        return dp.get(i).get(r);
    }
   
    // Function to initialize global variables
    // and find the initial value of 'R'
    static int PreCompute(int n, int c, int k)
    {
       
        // Resizing the variables
        for(int i = 0; i < k; i++)
        {
            exp_c.add(0);
        }
        exp_c.set(0, 1);
        for (int i = 1; i < k; i++)
        {
            exp_c.set(i,(exp_c.get(i - 1) * (c + 1)));
             
        }
        for (int i = 0; i < n; i++)
        {
            dp.add(new ArrayList());
        }
        for (int i = 0; i < n; i++)
        {
            for(int j = 0; j < (exp_c.get(k-1) * (c + 1)) ; j++ )
            {
                dp.get(i).add(0);
            }
        }
        for (int i = 0; i < n; i++)
        {
            v.add(new ArrayList(Arrays.asList(
              new Boolean[(exp_c.get(k-1) * (c + 1))])));
        }
        for (int i = 0; i < n; i++)
        {
            Collections.fill(v.get(i), Boolean.FALSE);
        }
         
        // Variable to store the initial value of R
        int R = 0;
        for(int i = 0; i < k; i++)
        {
            R += exp_c.get(i) * c;           
        }
        return R;
    }
   
    // Driver Code
    public static void main (String[] args)
    {
       
        // Input array
        int w[] = { 3, 8, 9 };
         
        // number of knapsacks and capacity
        int k = 1, c = 11;
        int n = w.length;
         
        // Performing required pre-computation
        int r = PreCompute(n, c, k);
         
        // finding the required answer
        System.out.println(FindMax(0, r, w, n, c, k));
    }
}
 
// This code is contributed by avanitrachhadiya2155


Python3
# 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


C#
using System;
using System.Collections.Generic;
 
class GFG{
 
// 2-d array to store if a state
// has been solved
static List> v = new List>();
 
// 2-d array to store states of DP
static List> dp = new List>();
 
// Vector to store power of variable 'C'.
static List exp_c = new List();
 
// Function to compute the states
static 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] = true;
    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] = Math.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'
static int PreCompute(int n, int c, int k)
{
     
    // Resizing the variables
    for(int i = 0; i < k; i++)
    {
        exp_c.Add(0);
    }
     
    exp_c[0] = 1;
    for(int i = 1; i < k; i++)
    {
        exp_c[i] = (exp_c[i - 1] * (c + 1));
    }
     
    for(int i = 0; i < n; i++)
    {
        dp.Add(new List());
    }
     
    for(int i = 0; i < n; i++)
    {
        for(int j = 0;
                j < (exp_c[k - 1] * (c + 1));
                j++ )
        {
            dp[i].Add(0);
        }
    }
     
    for(int i = 0; i < n; i++)
    {
        v.Add(new List());
    }
     
    for(int i = 0; i < n; i++)
    {
        for(int j = 0;
                j < (exp_c[k - 1] * (c + 1));
                j++ )
        {
            v[i].Add(false);
        }
    }
     
    // 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
static public void Main()
{
     
    // Input array
    int[] w = { 3, 8, 9 };
     
    // number of knapsacks and capacity
    int k = 1, c = 11;
    int n = w.Length;
     
    // Performing required pre-computation
    int r = PreCompute(n, c, k);
     
    // finding the required answer
    Console.WriteLine(FindMax(0, r, w, n, c, k));
}
}
 
// This code is contributed by rag2127


Javascript


输出:
11

时间复杂度: O(N*k*C^k)。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程