给定的 容量为W的 sac,以及两个长度为N 的数组 A[]和B[] ,其中A[i]表示第 i个黄金区块的重量, B[i]表示通过获取第i个区块获得的利润对于黄金,任务是找到通过取出部分或整个金块而获得的最大利润,该金块的平方重量不完美,不超过 sac 容量。
例子:
Input: A[]= {4, 5, 7}, B[] = {8, 5, 4), W = 10
Output: 7.857
Explanation:
One way to obtain the maximum profit is:
- Take the whole second block, getting a profit of 5 and reducing the capacity to 5.
- Take a fraction of 5/7 of the third block, getting a profit of (5/7)*4 = 2.857 and reducing the capacity to 0.
Thus, the maximum obtained profit is equal to (5+2.857 = 7.857), which is the maximum possible.
Input: A[]= {2, 5, 3}, B[] = {7, 6, 9), W = 8
Output: 19.600
方法:可以使用称为分数背包的贪婪算法来解决给定的问题。请按照以下步骤解决问题:
- 初始化成对向量V以存储通过将数组B[]中的数组元素作为第一个元素和数组B[] 中的数组元素作为第二个元素而形成的对,这些元素存在于相同的索引处。
- 在范围[0, N] 上迭代,如果A[i]不是完全平方数,则将{B[i], A[i]}对推入向量V 中。
- 通过自定义比较器按对的比率降序对向量 V 进行排序。
- 初始化一个变量,比如利润为0来存储最大利润。
- 遍历向量V并在每次迭代中执行以下步骤:
- 如果当前货币对的第二个元素小于或等于W ,则将利润增加该货币对的第一个元素,即取整块黄金,然后将W减少当前货币对的第二个元素。
- 否则,取等于W 与当前对的第二个元素的比率的数量,并将其存储在变量P 中。然后通过当前货币对的 P*first 元素增加利润,然后中断。
- 最后,在完成上述步骤后,打印在利润中获得的值作为答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Custom comparator
bool comp(pair p1,
pair p2)
{
long double a = p1.first, b = p1.second;
long double c = p2.first, d = p2.second;
long double val1 = 0, val2 = 0;
val1 = a / b;
val2 = c / d;
return val1 > val2;
}
// Function to find the maximum profit
long double maximumProfit(int A[], int B[], int N,
long long W)
{
// Stores the pairs of elements
// of B and A at the same index
vector > V;
// Iterate over the range
//[0, N]
for (int i = 0; i < N; i++) {
long long temp = sqrt(A[i]);
// If current integer is
// perfect square
if (temp * temp == A[i])
continue;
// Push the pair of B[i]
// and A[i] in vector V
V.push_back({ B[i], A[i] });
}
// Sorts the vector using
// the custom comparator
sort(V.begin(), V.end(), comp);
// Stores the maximum profit
long double profit = 0.00;
// Traverse the vector V
for (int i = 0; i < V.size(); i++) {
// If V[i].second is less
// than W
if (V[i].second <= W) {
// Increment profit by
// V[i].first
profit += V[i].first;
// Decrement V[i].second
// from W
W -= V[i].second;
}
// Otherwise
else {
// Update profit
profit += V[i].first
* ((long double)W / V[i].second);
break;
}
}
// Return the value of profit
return profit;
}
// Driver Code
int main()
{
int N = 3;
long long W = 10;
int A[] = { 4, 5, 7 };
int B[] = { 8, 5, 4 };
cout << maximumProfit(A, B, N, W) << endl;
return 0;
}
Python3
# Python3 program for the above approach
import math
from functools import cmp_to_key
# Custom comparator
def comparator(p1, p2):
a = p1[0]
b = p1[1]
c = p2[0]
d = p2[1]
val1 = a / b
val2 = c / d
return val1 > val2
# Function to find the maximum profit
def maximumProfit(A, B, N, W):
# Stores the pairs of elements
# of B and A at the same index
V = []
# Iterate over the range [0,N]
for i in range(0, N):
temp = int(math.sqrt(A[i]))
# If current integer is
# perfect square
if temp * temp == A[i]:
continue
# Push the pair of B[i]
# and A[i] in vector V
V.append([B[i], A[i]])
# Sort the vector using
# the custom comparator
V = sorted(V, key = cmp_to_key(comparator))
# Stores the maximum profit
profit = 0.00
# Traverse the vector V
k = len(V)
for i in range(k):
# If V[i][1] is less
# than W
if V[i][1] <= W:
# Increment profit by
# V[i][0]
profit += V[i][0]
# Decrement V[i][0]
# from W
W -= V[i][1]
# Otherwise
else:
# Update profit
profit += (V[i][0] * W) / V[i][1]
break
# Return the value of profit
return profit
# Driver Code
if __name__ == '__main__':
N = 3
W = 10
A = [ 4, 5, 7 ]
B = [ 8, 5, 4 ]
print(round(maximumProfit(A, B, N, W), 5))
# This code is contributed by MuskanKalra1
Javascript
输出
7.85714
时间复杂度: O(N * log(N))
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。