给定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)