给定一个由N 个元素组成的数组 arr[] ,任务是从给定数组中以可能的重复形式导出一个 MultiSet ,其中 MultiSet 的总和严格大于给定的数字 P,并且如果删除了任何元素,那么总和变得严格小于P 。打印给定数组的相应元素派生到 MultiSet 中的次数。如果无法导出这样的 MultiSet,则打印-1。
例子:
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 (
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.
方法:
上述问题的主要观察结果是,如果 P 不能被数组 arr[] 中的任何元素整除,那么我们取该元素的所有倍数,使得总和严格大于 p。但是如果数组中没有这样的元素并且多集是可能的,那么我们按降序对数组进行排序,并取每个元素的倍数小于P % arr[i]并不断更新 P。多集是不可能的如果每次更新的 P 都可以被 arr[i+1] 整除直到 N。下面是上述方法的实现:
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))
0 1
时间复杂度: O(N)
辅助空间: O(1)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live