Given two arrays A[] and B[] of N integers, the task is to find for each element A[i], the size of the smallest subset S of indices, such that :
- Each value corresponding to the indices in subset S is strictly less than A[i].
- Sum of elements corresponding to the indices in B is strictly greater than B[i].
Examples:
Input: N = 5, A = {3, 2, 100, 4, 5}, B = {1, 2, 3, 4, 5}
Output: {1, -1, 1, -1, 3}
Explanation: Subsets for each element of A are :
A[0] : {1}, (A[1] < A[0] and B[1] > B[0])
A[1] : {}, (no such subset exist )
A[2] : {4}, (A[4] < A[2] and B[4] > B[2])
A[3] : {}, (no such subset exist )
A[4] : {0, 1, 3}, (A[0] < A[4], A[1] < A[4], A[3] < A[4] and (B[0]+B[1]+B[3] > B[4]) )Input : N = 4, A = {1, 1, 1, 1}, B = {2, 4, 5, 9}
Output : {-1, -1, -1, -1}
Approach: The problem can be solved by a greedy approach using a multiset as per the following idea:
Sort the array A[] along with their indices and for each element in sorted array find the smallest subset having elements of B with sum greater than current element of B.
Use multiset in decreasing order to store elements of B.
Follow the below steps to solve this problem:
- Declare a vector v of pairs, that stores the elements of array A along with their indices.
- Sort the vector v. After sorting, the 1st condition is fulfilled for each element.
- Declare a multiset s so that elements in multiset are in decreasing order.
- Iterate through the vector v and at each ith iteration:
- Store the element in array B corresponding to the index in ith element of vector (i.e. 2nd element of pair) in a variable say curr_B.
- Iterate through the set, simultaneously keeping the count and sum of elements of the set, until the sum becomes just greater than curr_B.
- Insert curr_B into the set and count ( of the required set ) found for ith element into array storing answer (ans).
- Return the ans vector after the completion of all iteration.
Below is the implementation of the above approach :
// C++ program for Find minimum size of subset // for each index of the array satisfying the // given condition #include <bits/stdc++.h> 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<pair< int , int > > 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< int > ans(N);
// declaring a multiset to store the
// corresponding values of B
multiset< int , greater< int > > 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);
} |
import java.util.*;
import java.io.*;
// Java program for Find minimum size of subset // for each index of the array satisfying the // given condition public class GFG{
// Functions to print minimum size of subset
// for each element satisfying the given conditions
public static void printSubsets( int N, int A[], int B[]){
// Storing the elements of A along with
// their indices in a arrayList of pairs v
Pair v[] = new Pair[N];
for ( int i = 0 ; i < N ; i++){
v[i] = new Pair(A[i], i);
}
// Sorting the array v
Arrays.sort(v, new comp());
// Declaring a array of size N to
// store the answer
int ans[] = new int [N];
// Declaring a map to store the corresponding
// values of B
TreeMap<Integer, Integer> s = new TreeMap<Integer,Integer>();
// iterating through the sorted arraylist v.
// Since the arraylist 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 (Map.Entry<Integer, Integer> x : s.entrySet()) {
for ( int j= 1 ; j<=x.getValue() ; j++){
sum += (-x.getKey());
size += 1 ;
if (sum > curr_B)
break ;
}
if (sum > curr_B)
break ;
}
// inserting the current element of B
// into the TreeMap
if (s.containsKey(-curr_B)){
s.put(-curr_B, s.get(-curr_B)+ 1 );
} else {
s.put(-curr_B, 1 );
}
// 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++) {
System.out.print(ans[i] + " " );
}
}
// Driver code
public static void main(String args[])
{
int N = 5 ;
int A[] = { 3 , 2 , 100 , 4 , 5 };
int B[] = { 1 , 2 , 4 , 3 , 5 };
printSubsets(N, A, B);
}
} class Pair{
Integer first;
Integer second;
Pair( int x, int y){
this .first = x;
this .second = y;
}
} class comp implements Comparator<Pair>{
public int compare(Pair x, Pair y){
if (x.first.equals(y.first)){
return x.second.compareTo(y.second);
}
return x.first.compareTo(y.first);
}
} // This code is contributed by subhamgoyal2014. |
# 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. |
<script> // JS program for Find minimum size of subset // for each index of the array satisfying the // given condition // Functions to print minimum size of subset // for each element satisfying the given conditions function printSubsets(N, A, B)
{ // storing the elements of A along with
// their indices in a vector of pairs v
var v = [];
for ( var i = 0; i < N; i++) {
v.push([ A[i], i ]);
}
// sorting the vector v
v.sort();
// declaring a vector of size N to
// store the answer
var ans = new Array(N).fill(0);
// declaring a multiset to store the
// corresponding values of B
var 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 ( var i = 0; i < N; i++) {
var curr_B = B[v[i][1]];
var size = 0;
var sum = 0;
// iterating through the set to find
// the minimum set whose sum>B[i]
//(or curr_B)
for ( var j = 0; j < s.length; j++) {
sum += s[j];
size += 1;
if (sum > curr_B)
break ;
}
// inserting the current element of B
// into the sorted list s
// this implementation mimics
// C++ multiset or Python insort.
var ind = 0;
for ( var j = 0; j < s.length; j++) {
if (s[j] > curr_B)
break ;
ind++;
}
s.splice(ind, 0, 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][1]] = size;
}
// else we assign -1
else {
ans[v[i][1]] = -1;
}
}
// printing the answer
for ( var i = 0; i < N; i++) {
document.write(ans[i] + " " );
}
} // Driver Code var N = 5;
var A = [ 3, 2, 100, 4, 5 ];
var B = [ 1, 2, 4, 3, 5 ];
printSubsets(N, A, B); // This code is contributed by phasing17. </script> |
using System;
using System.Linq;
using System.Collections.Generic;
// C# program for Find minimum size of subset // for each index of the array satisfying the // given condition class GFG {
static void PrintSubsets( int N, int [] A, int [] B)
{
List<( int , int )> v = new List<( int , int )>();
for ( int i = 0; i < N; i++) {
v.Add((A[i], i));
}
v.Sort();
int [] ans = new int [N];
SortedSet< int > s = new SortedSet< int >();
for ( int i = 0; i < N; i++) {
int curr_B = B[v[i].Item2];
int size = 0;
int sum = 0;
foreach ( var x in s)
{
sum += x;
size += 1;
if (sum > curr_B)
break ;
}
s.Add(curr_B);
if (sum > curr_B) {
ans[v[i].Item2] = size;
}
else {
ans[v[i].Item2] = -1;
}
}
for ( int i = 0; i < N; i++) {
Console.Write(ans[i] + " " );
}
}
static void Main()
{
int N = 5;
int [] A = { 3, 2, 100, 4, 5 };
int [] B = { 1, 2, 4, 3, 5 };
PrintSubsets(N, A, B);
}
} |
1 -1 1 -1 3
Time Complexity : O(N^2)
Auxiliary Space : O(N)