Python 每k圈更换一次计数

Python 每k圈更换一次计数,python,algorithm,combinatorics,Python,Algorithm,Combinatorics,问题如下:您有n类型的项目,并且希望从中选择l(订单事项)。仅当自上次选择某一类型的项目以来,已选择了k其他项目时,才能对该类型的项目重新采样。计算可以形成的项目序列总数。如果这令人困惑,下面的示例将澄清问题: 说n=5,l=6,和k=3 答案是5*4*3*2*2*2。 在第一轮,我们可以选择5项中的任何一项。在第二次、第三次和第四次转弯时,我们可以选择4、3和2剩余项目中的任何一项。然后,在第五个转弯处,我们可以选择1,但也可以选择5,因为自上次拾取后,我们选择了3个其他项目,依此类推。因此,

问题如下:您有
n
类型的项目,并且希望从中选择
l
(订单事项)。仅当自上次选择某一类型的项目以来,已选择了
k
其他项目时,才能对该类型的项目重新采样。计算可以形成的项目序列总数。如果这令人困惑,下面的示例将澄清问题:

n=5
l=6
,和
k=3

答案是
5*4*3*2*2*2
。 在第一轮,我们可以选择5项中的任何一项。在第二次、第三次和第四次转弯时,我们可以选择
4
3
2
剩余项目中的任何一项。然后,在第五个转弯处,我们可以选择
1
,但也可以选择
5
,因为自上次拾取后,我们选择了3个其他项目,依此类推。因此,总计数为480

这里有一个简单的算法来解决这个问题:

def differentPlaylists(n, k, l):
    ans, choices = 1, n
    while l > 0:
        ans = (ans * choices) % 1000000007
        choices -= 1
        k, l = k - 1, l - 1
        if k < 0: choices += 1
    return ans
def不同播放列表(n、k、l):
ans,选项=1,n
当l>0时:
ans=(ans*选项)%100000007
选择-=1
k、 l=k-1,l-1
如果k<0:choices+=1
返回ans
这行得通,但太慢了。我想不出我怎么能在少于
l
multiply-ops的时间内生成一个算法来解决这个问题


有人能帮我弄清楚我怎么做吗?

看来你只需要精确数字的余数。答案是:
(n!/(n-k)!*(n-k)^(l-k))%M=
((n!/(n-k)!)%M)*((n-k)^(l-k)%M))%M


您不需要循环来查找
(n-k)^(l-k)%M
,您可以在
O(log(l-k))中使用它。如果
k
足够小,它将使整体计算大大加快,因为此公式的第一个阶乘部分是在解决方案中的
O(k)
中计算的。因此,在您的实现中,复杂性是
O(log(l-k))+O(k)
,而不是
O(l)

谢谢!我真的很努力地想弄清楚我如何优化组合参数,而我看不到所需的优化实际上是在指数运算中。这是一篇关于计算模m的指数的好文章: