📌  相关文章
📜  对于每个 A[i] 找到所有元素小于 A[i] 总和大于 B[i] 的最小子集

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

对于每个 A[i] 找到所有元素小于 A[i] 总和大于 B[i] 的最小子集

给定两个包含N个整数的数组A[]B[] ,任务是为每个元素 A[i] 找到索引的最小子集S的大小,这样:

  • 与子集S中的索引对应的每个值都严格小于A[i]
  • 与 B 中的索引对应的元素之和严格大于B[i]

例子:

方法:该问题可以通过使用多重集的贪心方法来解决,具体思路如下:

请按照以下步骤解决此问题:

  • 声明一个成对的向量v ,它存储数组 A 的元素及其索引。
  • 对向量v进行排序。排序后,每个元素都满足第一个条件。
  • 声明一个 multiset s ,以便 multiset 中的元素按降序排列。
  • 遍历向量v并在每次迭代时:
    • 将数组 B 中与向量的第 i 个元素(即对的第二个元素)中的索引相对应的元素存储在变量curr_B 中。
    • 遍历集合,同时保持集合元素的计数和总和,直到总和刚好大于curr_B
    • 将 curr_B 插入集合,并将为第 i 个元素找到的(所需集合的)计数到存储答案( ans)的数组中。
  • 完成所有迭代后返回ans向量。

以下是上述方法的实现:

C++
// C++ program for Find minimum size of subset
// for each index of the array satisfying the
// given condition
#include 
using namespace std;
 
// Functions to print minimum size of subset
// for each element satisfying the given conditions
void printSubsets(int N, int A[], int B[])
{
    // storing the elements of A along with
    // their indices in a vector of pairs v
    vector > v(N);
    for (int i = 0; i < N; i++) {
        v[i] = { A[i], i };
    }
 
    // sorting the vector v
    sort(v.begin(), v.end());
 
    // declaring a vector of size N to
    // store the answer
    vector ans(N);
 
    // declaring a multiset to store the
    // corresponding values of B
    multiset > s;
 
    // iterating through the sorted vector v.
    // Since the vector is  sorted, so the 1st
    // condition is already fulfilled, i.e.
    // all the elements of A at indices of resultant
    // set would be less than current A[i]
    for (int i = 0; i < N; i++) {
        int curr_B = B[v[i].second];
 
        int size = 0;
        int sum = 0;
        // iterating through the set to find
        // the minimum set whose sum>B[i]
        //(or curr_B)
        for (auto x : s) {
            sum += x;
            size += 1;
            if (sum > curr_B)
                break;
        }
 
        // inserting the current element of B
        // into the set
        s.insert(curr_B);
 
        // if sum>B[i] condition is fulfilled,
        // we assign size of resultant subset to
        // the answer at the index
        if (sum > curr_B) {
            ans[v[i].second] = size;
        }
 
        // else we assign -1
        else {
            ans[v[i].second] = -1;
        }
    }
 
    // printing the answer
    for (int i = 0; i < N; i++) {
        cout << ans[i] << " ";
    }
}
 
// Driver Code
int main()
{
    int N = 5;
    int A[] = { 3, 2, 100, 4, 5 };
    int B[] = { 1, 2, 4, 3, 5 };
    printSubsets(N, A, B);
}


Python3
# Python program to find the minimum size of the subset
# for each index of the array satisfying the given condition
import bisect
 
#Functions to print minimum size of subset
#for each element satisfying the given conditions
def printSubsets(N, A, B):
    #storing the elements of A along with
    #their indices in a vector of pairs v
    v = [[A[i], i] for i in range(N)]
     
    v.sort() #sorting v
     
    #initializing ans, s
    ans = [0] * N
    s = list()
 
     
    for i in range(N):
        curr_B = B[v[i][1]]
        size = 0
        sums = 0
 
        for ele in s:
            sums += ele
            size += 1
            if sums > curr_B:
                break
        #to ensure that sorted status of s is maintained
        bisect.insort(s, curr_B)
        if (sums > curr_B):
            ans[v[i][1]] = size
        else:
            ans[v[i][1]] = -1
 
    print(" ".join(list(map(str, ans))))
 
# Driver Code
N = 5
A = [3, 2, 100, 4, 5]
B = [1, 2, 4, 3, 5]
printSubsets(N, A, B)
 
# This code is contributed by phalasi.


输出
1 -1 1 -1 3 

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