给定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