📜  小背包查询

📅  最后修改于: 2021-05-07 05:15:21             🧑  作者: Mango

给定一个整数数组,该数组由正权重“ W”组成,值“ V”分别成对存在,而某些查询由一个整数“ C”组成,指定背包的容量,求出可以放入的产品的最大值如果允许物品破损,则采用背包。

例子:

建议您先阅读有关分数背包的这篇文章,然后再阅读本文。

天真的方法:一种简单的方法是按照V / W值的降序对数组进行排序,即存在值/权重比。然后,对于每个查询,我们将在knap-sack尚未完全满的情况下对数组求和,对所需的整数值进行迭代。
时间复杂度: O(q * n * log(n))

高效的方法:可以通过对权重和值执行排序数组的prefix_sum来优化查询。
下面是算法:

  1. 按值/重量比降序对数组进行排序。
  2. 分别找到数组的“权重”和“值”的前缀和。
    • 对于回答查询:
    • 执行二进制搜索以找到weight(W)上具有prefix_sum且大于’C’的第一个元素。严格来说,在“ W”的prefix_sum数组中找到“ C”的值的上限。假设此元素位于索引“ X”处。
    • 包括来自索引{0,X-1}的值的总和以及可以容纳在剩余容量中的来自索引’X’的分数值。

下面是上述方法的实现:

// C++ program to implement above approach
#include 
using namespace std;
  
// Function on the basis of which we will
// perform the sorting
bool comp(pair a, pair b)
{
    return (double)a.second / a.first >
                   (double)b.second / b.first;
}
  
// Function to sort the array on its value/weight
// and perform-sum on both weight and value
void preProcess(pair arr[], int n)
{
    sort(arr, arr + n, comp);
    for (int i = 1; i < n; i++) {
        arr[i].first += arr[i - 1].first;
        arr[i].second += arr[i - 1].second;
    }
}
  
// Function to answer queries
double maxValue(int w, pair arr[], int n)
{
    // If w is large enough
    // to cover all weights
    if (arr[n - 1].first <= w)
        return arr[n - 1].second;
  
    // Value to search on arr
    pair search_bound = { w, INT_MAX };
  
    // Index of the item which we will put
    // partially in our knap-sack
    int x = upper_bound(arr, arr + n, search_bound) - arr;
  
    // Required value
    if (x == 0)
        return (double)w * arr[0].second / arr[0].first;
    else
        return arr[x - 1].second +
              (double)(w - arr[x - 1].first) * 
              (arr[x].second - arr[x - 1].second) /
              (arr[x].first - arr[x - 1].first);
}
  
void PrintQueries(int query[], pair arr[],
                                        int n, int m)
{
    for (int i = 0; i < m; i += 1) {
        cout << maxValue(query[i], arr, n) << endl;
    }
}
  
// Driver code
int main()
{
    // Input array representing the data of w[] and v[]
    pair arr[] = { { 1, 2 }, { 1, 3 }, { 3, 7 } };
    int query[5] = { 1, 2, 3, 4, 5 };
  
    // Size of the array
    int n = sizeof(arr) / sizeof(pair);
    int m = sizeof(query) / sizeof(query[0]);
  
    // Pre-processing
    preProcess(arr, n);
  
    PrintQueries(query, arr, n, m);
  
    return 0;
}
输出:
3
5.33333
7.66667
10
12

时间复杂度: O((n + q)* log(n))