Alice has N coins of amount from 0 to (N-1). Bob wants to take k coins out of them, but Alice will only give if the set of K coins is interesting.
A set of coins is interesting if the sum of them is divisible by a unique integer M. Now Bob wants to know in how many ways he can get K coins.
Print the result by answer%(10^9+7)
Input format:- Three space separated integers N,K,M
Constraints:-
- 1 <= N, M <= 10 ^ 3
- 1 <= K <= 10 ^ 2
Sample input:- 4 2 2
Sample output:- 2({1,3},{2,4})
我尝试使用python库中的组合来解决这个问题,但结果超出了内存限制。 后来我使用递归方法对其进行测试,但它也导致超出了时间限制。,因为每个私有测试用例需要10秒的时间
有人能帮助有效地解决这个问题吗
递归方法的代码:
cou=0
n,k,m = input().split()
out_ = solve(k,m,n)
print(out_)
def getCombinations(data,n,k,m):
val=[0]*k
combiUtil(data,n,k,0,val,0,m)
def combiUtil(data,n,k,ind,val,i,m):
global cou
if(ind==k):
if(sum(val)%m==0):
cou+=1
return
if(i>=n):
return
val[ind]=data[i]
combiUtil(data,n,k,ind+1,val,i+1,m)
combiUtil(data,n,k,ind,val,i+1,m)
def solve(k,m,n):
global cou
k=int(k)
m=int(m)
n=int(n)
ans =0
data = [j for j in range(1,n+1)]
getCombinations(data,n,k,m)
return cou%(10**9+7)
如果你看一下“尝试所有组合”暴力解决方案的时间复杂性,它等于
O((N choose K) * K) = O(K * N^K
),因为有N choose K
种方法从1 to N
中选择K
个不同的整数,计算它们的和需要K-1
个加法。除了N
和K
的极小值之外,这是天文数字上的大更好的解决方案:动态规划
一个更快、更简单的解决方案是动态规划。我们可以把它写成一个3D动态规划问题:
公式中添加了很多边缘情况,但最重要的是最后一种情况:我们的动态编程子问题最多依赖于2个其他子问题,因此总运行时间是DP数组的大小:
O(nmk)
。下面是一个Python实现:参数是
N, K, M
,重命名为max_part_size, total_num_parts, mod
,如果没有分区,可以通过一些可选的预检查立即返回0
现在,假设您想做得比
O(nmk)
更好。在这里,事情变得棘手。如果你想做得更好,我能想象的唯一方法就是找到这些分区的生成函数,并使用FFT或其他快速多项式乘法模10**9 + 7
。首先,我建议使用math stackexchange上的this thread来研究如何做到这一点,这涉及到根据更为知名的分区号精确计算这些分区,其生成函数已经为人所知。即使如此,我也找不到任何关于生成函数是否具有短表示的内容,直接使用分区号并不能改善O(nmk)
的复杂性使用组合数学
如果您仍然想使用这种动态规划方法,可以使用组合数学进行一些小的修改,当
N
大于M*K
时,组合数学可能会渐进地更快:它在时间O((M*K)^2)
中运行,而时间不依赖于N
。我们的想法是使用我们的DP公式,但是我们现在不是从[1, ... N]
中选择K个不同的整数,而是从[0, ... M-1]
中选择K个(可能重复的)剩余类这是怎么回事?首先,我们需要计算
[1, ... N]
中有多少整数属于每个剩余类i mod M
。打这个电话R[i]
,换成0 <= i < M
。你可以这样计算现在我们可以编写一个稍加修改的动态规划定义和公式:
我希望你已经解决了这个问题。不过,我还是要为那些觉得这很有帮助的人回答这个问题
您已经尝试自己获取这些组合,但是您可以使用一个库来获取所有可能的组合,只需迭代并检查条件。如果目的不仅仅是为了学习,那么使用已经可用的代码总是可以的
无论如何,看看代码。谢谢
@kcsquared解决方案的三个NumPy版本,可在10秒时间限制内轻松解决最坏情况:
中小企业和最坏情况的基准:
基准代码(Try it online!):
相关问题 更多 >
编程相关推荐