给定两个数字和 .任务是找到的其中一个可以由一组表示方式的数量以至于并且这些数字的总和等于a 。还 (集合的最大大小不能超过m )。
例子:
Input : a = 4, m = 4
Output : 2 –> ({4}, {3, 1})
Note: {2, 2} is not a valid set as values are not in decreasing order
Input : a = 7, m = 5
Output : 5 –> ({7}, {6, 1}, {5, 2}, {4, 3}, {4, 2, 1})
方法:这个问题可以通过分而治之使用递归方法解决,它遵循以下条件:
- 如果a等于 0,则已找到一个解。
- 如果 a > 0 且 m == 0,则该集合违反条件,因为不能在该集合中添加更多值。
- 如果已经对 a 、 m和 prev (当前集合中包含的最后一个值)的给定值进行了计算,则返回该值。
- 从 i = a到 0 开始循环,如果 i < prev ,如果我们将 i包含在当前集合中并返回它,则计算解决方案的数量。
下面是上述方法的实现:
# Python3 code to calculate the number of ways
# in which a given number can be represented
# as set of finite numbers
# Import function to initialize the dictionary
from collections import defaultdict
# Initialize dictionary which is used
# to check if given solution is already
# visited or not to avoid
# calculating it again
visited = defaultdict(lambda : False)
# Initialize dictionary which is used to
# store the number of ways in which solution
# can be obtained for given values
numWays = defaultdict(lambda : 0)
# This function returns the total number
# of sets which satisfy given criteria
# a --> number to be divided into sets
# m --> maximum possible size of the set
# x --> previously selected value
def countNumOfWays(a, m, prev):
# number is divided properly and
# hence solution is obtained
if a == 0:
return 1
# Solution can't be obtained
elif a > 0 and m == 0:
return 0
# Return the solution if it has
# already been calculated
elif visited[(a, m, prev)] == True:
return numWays[(a, m, prev)]
else:
visited[(a, m, prev)] = True
for i in range(a, -1, -1):
# Continue only if current value is
# smaller compared to previous value
if i < prev:
numWays[(a,m,prev)] += countNumOfWays(a-i,m-1,i)
return numWays[(a, m, prev)]
# Values of 'a' and 'm' for which
# solution is to be found
# MAX_CONST is extremely large value
# used for first comparison in the function
a, m, MAX_CONST = 7, 5, 10**5
print(countNumOfWays(a, m, MAX_CONST))
输出:
5
时间复杂度: O(a*log(a))
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。