📜  选择给定重量和值比的最大重量

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

给定n个项目的权重和值以及值k。我们需要选择这些项目的子集,以使所选项目的权重总和与值总和之比为K,而权重之和在所有可能的子集选择中最大。

Input : weight[] = [4, 8, 9]
        values[] = [2, 4, 6]
        K = 2
Output : 12
We can choose only first and second item only, 
because (4 + 8) / (2 + 4) = 2 which is equal to K
we can't include third item with weight 9 because 
then ratio condition won't be satisfied so result 
will be (4 + 8) = 12

我们可以使用动态编程解决此问题。我们可以使状态为dp的状态为2,其中dp(i,j)在给定条件下,当项目总数为N且所需比率为K时,将存储最大可能的权重之和。
现在,在dp的两种状态下,我们将存储最后选择的项以及权重之和与值之和之间的差。我们将项目值乘以K,以便dp的第二状态将实际存储所选项目的(权重之和– K *(值之和))。现在我们可以看到答案将存储在dp(N-1,0)中,因为最后一项是第(N-1)个,因此所有项都将被考虑,权重之和与K *(值之和)之差为0表示权重之和,值之和的比率为K。
在定义了上面的dp状态之后,我们可以简单地编写状态之间的转换,如下所示,

dp(last, diff) = max (dp(last - 1, diff),    
                 dp(last-1, diff + wt[last] - val[last]*K))

dp(last – 1, diff) represents the condition when current
                   item is not chosen and 
dp(last – 1, diff + wt[last] – val[last] * K)) represents 
the condition when current item is chosen so difference 
is updated with weight and value of current item.

在下面的代码中,自上而下的方法用于解决此动态编程问题,并且用于存储dp状态,因此使用了映射,因为这种差异也可能为负,并且在这种情况下2D阵列也会产生问题,需要特别注意。

C++
// C++ program to choose item with maximum
// sum of weight under given constraint
#include 
using namespace std;
  
// memoized recursive method to return maximum
// weight with K as ratio of weight and values
int maxWeightRec(int wt[], int val[], int K,
                  map, int>& mp,
                            int last, int diff)
{
    //  base cases : if no item is remaining
    if (last == -1)
    {
        if (diff == 0)
            return 0;
        else
            return INT_MIN;
    }
  
    // first make pair with last chosen item and
    // difference between weight and values
    pair tmp = make_pair(last, diff);
    if (mp.find(tmp) != mp.end())
        return mp[tmp];
  
    /*  choose maximum value from following two
        1) not selecting the current item and calling
           recursively
        2) selection current item, including the weight
           and updating the difference before calling
           recurively */
    mp[tmp] = max(maxWeightRec(wt, val, K, mp, last - 1, diff),
                   wt[last] + maxWeightRec(wt, val, K, mp,
                   last - 1, diff + wt[last] - val[last] * K));
  
    return mp[tmp];
}
  
// method returns maximum sum of weight with K
// as ration of sum of weight and their values
int maxWeight(int wt[], int val[], int K, int N)
{
    map, int> mp;
    return maxWeightRec(wt, val, K, mp, N - 1, 0);
}
  
//  Driver code to test above methods
int main()
{
    int wt[] = {4, 8, 9};
    int val[] = {2, 4, 6};
    int N = sizeof(wt) / sizeof(int);
    int K = 2;
  
    cout << maxWeight(wt, val, K, N);
    return 0;
}


Java
// Java program to choose item with maximum
// sum of weight under given constraint
  
import java.awt.Point;
import java.util.HashMap;
  
class Test
{
    // memoized recursive method to return maximum
    // weight with K as ratio of weight and values
    static int maxWeightRec(int wt[], int val[], int K,
                      HashMap hm,
                                int last, int diff)
    {
        //  base cases : if no item is remaining
        if (last == -1)
        {
            if (diff == 0)
                return 0;
            else
                return Integer.MIN_VALUE;
        }
       
        // first make pair with last chosen item and
        // difference between weight and values
        Point tmp = new Point(last, diff);
        if (hm.containsKey(tmp))
            return hm.get(tmp);
       
        /*  choose maximum value from following two
            1) not selecting the current item and calling
               recursively
            2) selection current item, including the weight
               and updating the difference before calling
               recursively */
       hm.put(tmp,Math.max(maxWeightRec(wt, val, K, hm, last - 1, diff),
                       wt[last] + maxWeightRec(wt, val, K, hm,
                       last - 1, diff + wt[last] - val[last] * K)));
       
        return hm.get(tmp);
    }
       
    // method returns maximum sum of weight with K
    // as ration of sum of weight and their values
    static int maxWeight(int wt[], int val[], int K, int N)
    {
        HashMap hm = new HashMap<>();
        return maxWeightRec(wt, val, K, hm, N - 1, 0);
    }
      
    // Driver method
    public static void main(String args[])
    {
        int wt[] = {4, 8, 9};
        int val[] = {2, 4, 6};
          
        int K = 2;
       
        System.out.println(maxWeight(wt, val, K, wt.length));
    }
}
// This code is contributed by Gaurav Miglani


Python3
# Python3 program to choose item with maximum
# sum of weight under given constraint
INT_MIN = -9999999999
  
def maxWeightRec(wt, val, K, mp, last, diff):
      
    # memoized recursive method to return maximum
    # weight with K as ratio of weight and values
  
    # base cases : if no item is remaining
    if last == -1:
        if diff == 0:
            return 0
        else:
            return INT_MIN
  
    # first make pair with last chosen item and
    # difference between weight and values
    tmp = (last, diff)
    if tmp in mp:
        return mp[tmp]
  
    # choose maximum value from following two
    # 1) not selecting the current item and 
    #    calling recursively
    # 2) selection current item, including 
    #    the weight and updating the difference 
    #    before calling recursively
  
    mp[tmp] = max(maxWeightRec(wt, val, K, mp, 
                               last - 1, diff), wt[last] + 
                  maxWeightRec(wt, val, K, mp, 
                               last - 1, diff + 
                               wt[last] - val[last] * K))
    return mp[tmp]
  
def maxWeight(wt, val, K, N):
      
    # method returns maximum sum of weight with K
    # as ration of sum of weight and their values
    return maxWeightRec(wt, val, K, {}, N - 1, 0)
  
# Driver code
if __name__ == "__main__":
    wt = [4, 8, 9]
    val = [2, 4, 6]
    N = len(wt)
    K = 2
    print(maxWeight(wt, val, K, N))
  
# This code is contributed 
# by vibhu4agarwal


输出:

12