📜  0-1背包中N个物品的最大价值总和,最多将K个物品的重量减半

📅  最后修改于: 2022-05-13 01:56:10.298000             🧑  作者: Mango

0-1背包中N个物品的最大价值总和,最多将K个物品的重量减半

给定N件物品的重量价值以及背包的容量W。还假设最多可以将K件物品的重量更改为其原始重量的一半。任务是找到可以得到的N个物品的最大价值总和,使得背包中物品的重量总和不超过给定的容量W。

例子:

方法:给定问题是 0 1 背包问题的变体。标志表示重量已减半的项目数。在每次递归调用时,计算并返回以下情况的最大值:

  • 基本情况:如果索引超过值的长度,则返回零
  • 如果 flag 等于K,则最大值 考虑2种情况:
    • 如果物品的重量不超过剩余重量,则包括物品的全重
    • 跳过项目
  • 如果 flag 小于K,则最大值 考虑3种情况:
    • 如果物品的重量不超过剩余重量,则包括物品的全重
    • 如果物品的一半重量不超过剩余重量,则包括一半重量的物品
    • 跳过项目
C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
// Function to find the maximum  value
 
int maximum(int value[],
            int weight[], int weight1,
            int flag, int K, int index, int val_len)
{
 
    // base condition
    if (index >= val_len)
    {
 
        return 0;
    }
 
    // K elements already reduced
    // to half of their weight
    if (flag == K)
    {
 
        // Dont include item
        int skip = maximum(value,
                           weight, weight1,
                           flag, K, index + 1, val_len);
 
        int full = 0;
 
        // If weight of the item is
        // less than  or equal to the
        // remaining weight then include
        // the item
        if (weight[index] <= weight1)
        {
 
            full = value[index] + maximum(
                                      value, weight,
                                      weight1 - weight[index], flag,
                                      K, index + 1, val_len);
        }
 
        // Return the maximum  of
        // both cases
        return max(full, skip);
    }
 
    // If the weight reduction to half
    // is possible
    else
    {
 
        // Skip the item
        int skip = maximum(
            value, weight,
            weight1, flag,
            K, index + 1, val_len);
 
        int full = 0;
        int half = 0;
 
        // Include item with full weight
        // if weight of the item is less
        // than the remaining weight
        if (weight[index] <= weight1)
        {
 
            full = value[index] + maximum(
                                      value, weight,
                                      weight1 - weight[index],
                                      flag, K, index + 1, val_len);
        }
 
        // Include item with half weight
        // if half weight of the item is
        // less than the remaining weight
        if (weight[index] / 2 <= weight1)
        {
 
            half = value[index] + maximum(
                                      value, weight,
                                      weight1 - weight[index] / 2,
                                      flag, K, index + 1, val_len);
        }
 
        // Return the maximum of all 3 cases
        return max(full,
                   max(skip, half));
    }
}
int main()
{
 
    int value[] = {17, 20, 10, 15};
    int weight[] = {4, 2, 7, 5};
    int K = 1;
    int W = 4;
    int val_len = sizeof(value) / sizeof(value[0]);
    cout << (maximum(value, weight, W,
                     0, K, 0, val_len));
 
    return 0;
}
 
// This code is contributed by Potta Lokesh


Java
// Java implementation for the above approach
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to find the maximum  value
    static int maximum(int value[],
                       int weight[], int weight1,
                       int flag, int K, int index)
    {
 
        // base condition
        if (index >= value.length) {
 
            return 0;
        }
 
        // K elements already reduced
        // to half of their weight
        if (flag == K) {
 
            // Dont include item
            int skip = maximum(value,
                               weight, weight1,
                               flag, K, index + 1);
 
            int full = 0;
 
            // If weight of the item is
            // less than  or equal to the
            // remaining weight then include
            // the item
            if (weight[index] <= weight1) {
 
                full = value[index]
                       + maximum(
                             value, weight,
                             weight1 - weight[index], flag,
                             K, index + 1);
            }
 
            // Return the maximum  of
            // both cases
            return Math.max(full, skip);
        }
 
        // If the weight reduction to half
        // is possible
        else {
 
            // Skip the item
            int skip = maximum(
                value, weight,
                weight1, flag,
                K, index + 1);
 
            int full = 0;
            int half = 0;
 
            // Include item with full weight
            // if weight of the item is less
            // than the remaining weight
            if (weight[index] <= weight1) {
 
                full = value[index]
                       + maximum(
                             value, weight,
                             weight1 - weight[index],
                             flag, K, index + 1);
            }
 
            // Include item with half weight
            // if half weight of the item is
            // less than the remaining weight
            if (weight[index] / 2 <= weight1) {
 
                half = value[index]
                       + maximum(
                             value, weight,
                             weight1 - weight[index] / 2,
                             flag, K, index + 1);
            }
 
            // Return the maximum of all 3 cases
            return Math.max(full,
                            Math.max(skip, half));
        }
    }
 
    public static void main(String[] args)
        throws Exception
    {
 
        int value[] = { 17, 20, 10, 15 };
        int weight[] = { 4, 2, 7, 5 };
        int K = 1;
        int W = 4;
        System.out.println(
            maximum(value, weight, W,
                    0, K, 0));
    }
}


Python3
# Python program for the above approach
 
# Function to find the maximum  value
def maximum(value,
            weight, weight1,
            flag, K, index, val_len) :
                 
 
    # base condition
    if (index >= val_len) :
 
        return 0
     
 
    # K elements already reduced
    # to half of their weight
    if (flag == K) :
 
        # Dont include item
        skip = maximum(value,
                           weight, weight1,
                           flag, K, index + 1, val_len)
 
        full = 0
 
        # If weight of the item is
        # less than  or equal to the
        # remaining weight then include
        # the item
        if (weight[index] <= weight1) :
 
            full = value[index] + maximum(
                                      value, weight,
                                      weight1 - weight[index], flag,
                                      K, index + 1, val_len)
         
 
        # Return the maximum  of
        # both cases
        return max(full, skip)
     
 
    # If the weight reduction to half
    # is possible
    else :
 
        # Skip the item
        skip = maximum(
            value, weight,
            weight1, flag,
            K, index + 1, val_len)
 
        full = 0
        half = 0
 
        # Include item with full weight
        # if weight of the item is less
        # than the remaining weight
        if (weight[index] <= weight1) :
 
            full = value[index] + maximum(
                                      value, weight,
                                      weight1 - weight[index],
                                      flag, K, index + 1, val_len)
         
 
        # Include item with half weight
        # if half weight of the item is
        # less than the remaining weight
        if (weight[index] / 2 <= weight1) :
 
            half = value[index] + maximum(
                                      value, weight,
                                      weight1 - weight[index] / 2,
                                      flag, K, index + 1, val_len)
         
 
        # Return the maximum of all 3 cases
        return max(full,
                   max(skip, half))
     
 
# Driver Code
 
value =  [ 17, 20, 10, 15 ]
weight = [ 4, 2, 7, 5 ]
K = 1
W = 4
val_len = len(value)
print(maximum(value, weight, W,
                     0, K, 0, val_len))
 
# This code is contributed by sanjoy_62.


C#
// C# implementation for the above approach
using System;
 
public class GFG {
 
    // Function to find the maximum  value
    static int maximum(int []value,
                       int []weight, int weight1,
                       int flag, int K, int index)
    {
 
        // base condition
        if (index >= value.Length) {
 
            return 0;
        }
 
        // K elements already reduced
        // to half of their weight
        if (flag == K) {
 
            // Dont include item
            int skip = maximum(value,
                               weight, weight1,
                               flag, K, index + 1);
 
            int full = 0;
 
            // If weight of the item is
            // less than  or equal to the
            // remaining weight then include
            // the item
            if (weight[index] <= weight1) {
 
                full = value[index]
                       + maximum(
                             value, weight,
                             weight1 - weight[index], flag,
                             K, index + 1);
            }
 
            // Return the maximum  of
            // both cases
            return Math.Max(full, skip);
        }
 
        // If the weight reduction to half
        // is possible
        else {
 
            // Skip the item
            int skip = maximum(
                value, weight,
                weight1, flag,
                K, index + 1);
 
            int full = 0;
            int half = 0;
 
            // Include item with full weight
            // if weight of the item is less
            // than the remaining weight
            if (weight[index] <= weight1) {
 
                full = value[index]
                       + maximum(
                             value, weight,
                             weight1 - weight[index],
                             flag, K, index + 1);
            }
 
            // Include item with half weight
            // if half weight of the item is
            // less than the remaining weight
            if (weight[index] / 2 <= weight1) {
 
                half = value[index]
                       + maximum(
                             value, weight,
                             weight1 - weight[index] / 2,
                             flag, K, index + 1);
            }
 
            // Return the maximum of all 3 cases
            return Math.Max(full,
                            Math.Max(skip, half));
        }
    }
 
  // Driver code
    public static void Main(String[] args)
    {
 
        int []value = { 17, 20, 10, 15 };
        int []weight = { 4, 2, 7, 5 };
        int K = 1;
        int W = 4;
        Console.WriteLine(
            maximum(value, weight, W,
                    0, K, 0));
    }
}
 
// This code is contributed by shikhasingrajput


Javascript


输出
37

时间复杂度: O(3^N)
辅助空间: O(N)