GeeksforGeeks App
Open App
Browser
Continue

Derive a MultiSet from given Array such that sum is > P and removing any element makes sum < P

Given an array arr[] of N elements, the task is to derive a MultiSet having the numbers from the given array in possible repetitions, such that the sum of the MultiSet is strictly greater than given number P and if any of the element is removed, then the sum becomes strictly less than P. Print the number of times the corresponding element of given array is derived into the MultiSet. Print -1 if no such MultiSet can be derived.

Examples:

Input: arr[] = [1, 5], P = 4
Output: [0, 1]
Explanation:
Here, if number 1 is taken 0 times, and 5 is taken 1 time, the MultiSet becomes: [5]
Therefore, sum = 5 (>P) and removing 5 makes sum = 0 (<P). Hence, the required MultiSet is [5].
Therefore, the output is [0, 1] as the number of times 1 and 5 are taken respectively.

Input: arr[] = [1, 5], P = 10
Output: -1
Explanation:
If we take a multiset as [1, 5, 5], the sum will be > P, but removing 1 will not make sum < P. Hence, no such MultiSet can be derived in this case.

Approach:
The main observation of the above problem is, if P is indivisible by any of the elements in array arr[], then we take all the multiples of that element such that the sum is strictly greater than p. But if there is no such element in the array and the multiset is possible then we sort the array in descending order and take multiples of each element one less than P % arr[i] and keep updating the P. The multi set is not possible if every time the updated P is divisible by arr[i+1] till N.

Below is the implementation of above approach:

C++

 `// C++ implementation to Derive a``// MultiSet from given Array such that``// sum is > P and removing any``// element makes sum < P``#include ``using` `namespace` `std;` `// Function to derive the multiset``string Multiset (``int` `n, ``int` `p, ``int` `arr[]){` `  ``int` `c = 0;` `  ``for` `(``int` `i = 0; i < n; i++)``  ``{` `    ``int` `j = arr[i];` `    ``// Check if p is indivisible``    ``// by any element in arr``    ``if` `(p % j != 0){``      ``c = j;``      ``break``;``    ``}``  ``}` `  ``// Check if there is no element in``  ``// arr which cannot divide p   ``  ``if` `(c == 0){` `    ``int` `d[n];``    ``for` `(``int` `i = 0; i < n; i++)``      ``d[i] = arr[i];` `    ``sort(d, d + n);` `    ``// Sort arr in descending order``    ``int` `coun = 0;` `    ``int` `pri[n];``    ``for` `(``int` `i = 0; i < n; i++)``      ``pri[i] = 0;` `    ``// Assigning multiples of each element``    ``while` `(coun != n && p % d[coun] == 0)``    ``{``      ``auto` `b = find(arr, arr + n, d[coun]) - arr;``      ``pri[b] =((p/d[coun]) - 1);``      ``p = p - (d[coun]*((p/d[coun]) - 1));``      ``coun += 1;``    ``}` `    ``// Check if there is no case``    ``// of getting sum > p``    ``if` `(coun == n)``      ``return` `(``"NO"``);` `    ``else` `if` `(p % d[coun] != 0){``      ``int` `y = (p/d[coun]) + 1;``      ``int` `k = find(arr, arr + n, d[coun]) - arr;` `      ``pri[k] = y;``      ``string s = ``""``;` `      ``// Multi set``      ``for` `(``auto` `j : pri)                    ``        ``s = s + to_string(j) + ``" "``;``      ``return` `(s);``    ``}` `  ``}` `  ``else``{``    ``int` `k = (p/c);``    ``int` `b = c * (k + 1);` `    ``int` `m[n];``    ``for` `(``int` `i = 0; i < n; i++)``      ``m[i] = 0;` `    ``auto` `q = find(arr, arr + n, c) - arr;``    ``m[q] = (b/c);``    ``string s = ``""``;``    ``for` `(``auto` `j : m)``      ``s = s + to_string(j) + ``" "``;``    ``return` `(s);``  ``}``}` `// Driver code``int` `main()``{``  ``int` `N = 2;``  ``int` `P = 4;``  ``int` `arr[] = {1, 5};``  ``cout << Multiset(N, P, arr);``}` `// This code is contributed by phasing17.`

Java

 `// Java implementation to Derive a``// MultiSet from given Array such that``// sum is > P and removing any``// element makes sum < P``import` `java.util.*;` `class` `GFG``{``  ``// Function to derive the multiset``  ``static` `String Multiset (``int` `n, ``int` `p, ``int``[] arr){` `    ``int` `c = ``0``;` `    ``for` `(``int` `i = ``0``; i < n; i++)``    ``{` `      ``int` `j = arr[i];` `      ``// Check if p is indivisible``      ``// by any element in arr``      ``if` `(p % j != ``0``){``        ``c = j;``        ``break``;``      ``}``    ``}` `    ``// Check if there is no element in``    ``// arr which cannot divide p   ``    ``if` `(c == ``0``){` `      ``int``[] d = ``new` `int``[n];``      ``for` `(``int` `i = ``0``; i < n; i++)``        ``d[i] = arr[i];` `      ``Arrays.sort(d);` `      ``// Sort arr in descending order``      ``int` `coun = ``0``;` `      ``int``[] pri = ``new` `int``[n];``      ``for` `(``int` `i = ``0``; i < n; i++)``        ``pri[i] = ``0``;` `      ``// Assigning multiples of each element``      ``while` `(coun != n && p % d[coun] == ``0``)``      ``{``        ``int` `b = Arrays.binarySearch(arr, d[coun]);``        ``if` `(b == -``1``)``          ``b = n;` `        ``pri[b] =((p/d[coun]) - ``1``);``        ``p = p - (d[coun]*((p/d[coun]) - ``1``));``        ``coun += ``1``;``      ``}` `      ``// Check if there is no case``      ``// of getting sum > p``      ``if` `(coun == n)``        ``return` `(``"NO"``);` `      ``else` `if` `(p % d[coun] != ``0``){``        ``int` `y = (p/d[coun]) + ``1``;``        ``int` `k = Arrays.binarySearch(arr, d[coun]);``        ``if` `(k == -``1``)``          ``k = n;` `        ``pri[k] = y;``        ``String s = ``""``;` `        ``// Multi set``        ``for` `(var j : pri)                    ``          ``s = s + String.valueOf(j) + ``" "``;``        ``return` `(s);``      ``}` `    ``}` `    ``else``{``      ``int` `k = (p/c);``      ``int` `b = c * (k + ``1``);` `      ``int``[] m = ``new` `int``[n];``      ``for` `(``int` `i = ``0``; i < n; i++)``        ``m[i] = ``0``;` `      ``int` `q = Arrays.binarySearch(arr, c);``      ``if` `(c == -``1``)``        ``c = n;` `      ``m[q] = (b/c);``      ``String s = ``""``;``      ``for` `(var j : m)``        ``s = s + String.valueOf(j) + ``" "``;``      ``return` `(s);``    ``}` `    ``return` `""``;``  ``}` `  ``// Driver code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int` `N = ``2``;``    ``int` `P = ``4``;``    ``int``[] arr = {``1``, ``5``};``    ``System.out.println(Multiset(N, P, arr));``  ``}``}` `// This code is contributed by phasing17.`

Python3

 `# Python implementation to Derive a``# MultiSet from given Array such that``# sum is > P and removing any``# element makes sum < P` `# Function to derive the multiset``def` `Multiset (n, p, arr):``    ` `    ``c ``=` `0``    ` `    ``for` `j ``in` `arr:``        ` `        ``# Check if p is indivisible``        ``# by any element in arr``        ``if` `(p ``%` `j !``=` `0``):``            ``c ``=` `j``            ``break``            ` `    ``# Check if there is no element in``    ``# arr which cannot divide p   ``    ``if` `(c ``=``=` `0``):``        ` `        ``d ``=` `sorted``(arr)``        ` `        ``# Sort arr in descending order``        ``d ``=` `d[::``-``1``]        ``        ``coun ``=` `0``        ``pri ``=` `[``0``] ``*` `n``        ` `        ``# Assigning multiples of each element``        ``while` `(coun !``=` `n ``and` `p ``%` `d[coun] ``=``=` `0``):``          ` `            ``b ``=` `arr.index(d[coun])``            ``pri[b] ``=` `((p``/``/``d[coun]) ``-` `1``)``            ``p ``=` `p ``-` `(d[coun]``*``((p``/``/``d[coun]) ``-` `1``))``            ``coun ``+``=` `1``        ` `        ``# Check if there is no case``        ``# of getting sum > p``        ``if` `(coun ``=``=` `n):``            ``return` `(``"NO"``)``            ` `        ``elif` `(p ``%` `d[coun] !``=` `0``):``            ``y ``=` `(p``/``/``d[coun]) ``+` `1``            ``k ``=` `arr.index(d[coun])``            ` `            ``pri[k] ``=` `y``            ``s ``=` `""``            ` `            ``# Multi set``            ``for` `j ``in` `pri:                    ``                ``s ``=` `s ``+` `str``(j) ``+` `" "``            ``return` `(s)``        ` `            ` `    ``else``:``        ``k ``=` `p``/``/``c``        ``b ``=` `c ``*` `(k ``+` `1``)``        ``m ``=` `[``0``] ``*` `n``        ``q ``=` `arr.index(c)``        ``m[q] ``=` `b``/``/``c``        ``s ``=` `""``        ``for` `j ``in` `m:``            ``s ``=` `s ``+` `str``(j) ``+` `" "``        ``return` `(s)` `# Driver code``N, P ``=` `2``, ``4``arr ``=` `[``1``, ``5``]``print` `(Multiset(N, P, arr))`

C#

 `// C# implementation to Derive a``// MultiSet from given Array such that``// sum is > P and removing any``// element makes sum < P``using` `System;``using` `System.Collections.Generic;` `class` `GFG``{``  ``// Function to derive the multiset``  ``static` `string` `Multiset (``int` `n, ``int` `p, ``int``[] arr){` `    ``int` `c = 0;` `    ``for` `(``int` `i = 0; i < n; i++)``    ``{` `      ``int` `j = arr[i];` `      ``// Check if p is indivisible``      ``// by any element in arr``      ``if` `(p % j != 0){``        ``c = j;``        ``break``;``      ``}``    ``}` `    ``// Check if there is no element in``    ``// arr which cannot divide p   ``    ``if` `(c == 0){` `      ``int``[] d = ``new` `int``[n];``      ``for` `(``int` `i = 0; i < n; i++)``        ``d[i] = arr[i];` `      ``Array.Sort(d);` `      ``// Sort arr in descending order``      ``int` `coun = 0;` `      ``int``[] pri = ``new` `int``[n];``      ``for` `(``int` `i = 0; i < n; i++)``        ``pri[i] = 0;` `      ``// Assigning multiples of each element``      ``while` `(coun != n && p % d[coun] == 0)``      ``{``        ``int` `b = Array.IndexOf(arr, d[coun]);``        ``if` `(b == -1)``          ``b = n;` `        ``pri[b] =((p/d[coun]) - 1);``        ``p = p - (d[coun]*((p/d[coun]) - 1));``        ``coun += 1;``      ``}` `      ``// Check if there is no case``      ``// of getting sum > p``      ``if` `(coun == n)``        ``return` `(``"NO"``);` `      ``else` `if` `(p % d[coun] != 0){``        ``int` `y = (p/d[coun]) + 1;``        ``int` `k = Array.IndexOf(arr, d[coun]);``        ``if` `(k == -1)``          ``k = n;` `        ``pri[k] = y;``        ``string` `s = ``""``;` `        ``// Multi set``        ``foreach` `(``var` `j ``in` `pri)                    ``          ``s = s + Convert.ToString(j) + ``" "``;``        ``return` `(s);``      ``}` `    ``}` `    ``else``{``      ``int` `k = (p/c);``      ``int` `b = c * (k + 1);` `      ``int``[] m = ``new` `int``[n];``      ``for` `(``int` `i = 0; i < n; i++)``        ``m[i] = 0;` `      ``int` `q = Array.IndexOf(arr, c);``      ``if` `(c == -1)``        ``c = n;` `      ``m[q] = (b/c);``      ``string` `s = ``""``;``      ``foreach` `(``var` `j ``in` `m)``        ``s = s + Convert.ToString(j) + ``" "``;``      ``return` `(s);``    ``}` `    ``return` `""``;``  ``}` `  ``// Driver code``  ``public` `static` `void` `Main(``string``[] args)``  ``{``    ``int` `N = 2;``    ``int` `P = 4;``    ``int``[] arr = {1, 5};``    ``Console.WriteLine(Multiset(N, P, arr));``  ``}``}` `// This code is contributed by phasing17.`

Javascript

 `// JavaScript implementation to Derive a``// MultiSet from given Array such that``// sum is > P and removing any``// element makes sum < P` `// Function to derive the multiset``function` `Multiset (n, p, arr){``    ` `    ``let c = 0``    ` `    ``for` `(let j of arr)``    ``{``        ` `        ``// Check if p is indivisible``        ``// by any element in arr``        ``if` `(p % j != 0){``            ``c = j``            ``break``        ``}``    ``}``            ` `    ``// Check if there is no element in``    ``// arr which cannot divide p   ``    ``if` `(c == 0){``        ` `        ``let d = [...arr]``        ``d.sort(``function``(a, b) { ``return` `a - b})``        ` `        ``// Sort arr in descending order``        ``d.reverse()       ``        ``let coun = 0``        ``let pri = ``new` `Array(n).fill(0)``        ` `        ``// Assigning multiples of each element``        ``while` `(coun != n && p % d[coun] == 0)``        ``{``          ` `            ``let b = arr.indexOf(d[coun])``            ``pri[b] = Math.floor((p/d[coun]) - 1)``            ``p = p - Math.floor(d[coun]*((p/d[coun]) - 1))``            ``coun += 1``        ``}``        ` `        ``// Check if there is no case``        ``// of getting sum > p``        ``if` `(coun == n)``            ``return` `(``"NO"``)``            ` `        ``else` `if` `(p % d[coun] != 0){``            ``let y = Math.floor(p/d[coun]) + 1``            ``let k = arr.indexOf(d[coun])``            ` `            ``pri[k] = y``            ``let s = ``""``            ` `            ``// Multi set``            ``for` `(let j of pri)                    ``                ``s = s + (j).toString() + ``" "``            ``return` `(s)``        ``}``        ` `    ``}``            ` `    ``else``{``        ``let k = Math.floor(p/c)``        ``let b = c * (k + 1)``        ``let m = ``new` `Array(n).fill(0)``        ``let q = arr.indexOf(c)``        ``m[q] = Math.floor(b/c)``        ``let s = ``""``        ``for` `(let j of m)``            ``s = s + (j).toString() + ``" "``        ``return` `(s)``    ``}``}` `// Driver code``let N = 2``let P = 4``let arr = [1, 5]``console.log(Multiset(N, P, arr))` `// This code is contributed by phasing17.`

Output

`0 1 `

Time Complexity: O(N)
Auxiliary Space: O(1)

My Personal Notes arrow_drop_up