我觉得你的问题可以表述为如下:
有多少个排列有元素a_0, a_1, ... a_n-1, b_0, b_1, ..., b_m-1
的列表,其中没有a_k
元素位于k
? (让我们表示与p_{n,m}
这个数字 - 您的具体问题是p_{6,5}
值)。
请注意,您的建议公式5 * 6是因为以下的不正确: 它只能算作案件,其中!在a_k
s为前6位(没有任何人在自己的索引的位置是的),和b_k
S于最后5 你不要指望像任何其他配置:a_3, b_4, b_1, a_0, a_5, b_0, a_2, b_2, b_3, a_1, a_4
,这里的顺序是完全混合。
对于所有元素中的!11元素紊乱的子集,您的其他想法也是不正确的,因为任何b_k
都可以在任何位置。
但是,根据a_0
的位置,我们可以通过将p_{n,m}
的递归公式分为两种情况轻松添加递归公式。
如果a_0
获取位置1, 2, ..., n-1
之一。 (n-1
不同的可能性。) 这意味着a_0
都不在位置0
,并且它还通过占据该位置防止另一个a_k
位于位置k
。因此,这个a_k
成为'自由',它可以去任何其他职位。如果a_0
以这种方式得到修复,其他元素可以通过不同的方式以p_{n-2,m+1}
进行排列。
如果a_0
进入n, n+1, ..., n+m-1
的其中一个位置。 (m
不同的可能性)。 这种方式没有其他a_k
被阻止在对应于它的索引的位置。其他元素可以用p_{n-1,m}
不同的方式排列。
将它们加在一起给出了递归:p_{n,m} = (n-1)*p_{n-2,m+1} + m*p_{n-1,m}
。因为它意味着每个元素可以在任何位置,所以每个m
停止条件为p_{0,m}=m!
。
我也编码它的Python:
import math
def derange(n,m):
if n<0:
return 0
elif n==0:
return math.factorial(m)
else:
return (n-1)*derange(n-2, m+1) + m*derange(n-1, m)
print derange(6,5)
给22852200.
如果你有兴趣在一般情况下,你可以找到一些OEIS相关序列。 搜索词“差异因子数”可能很有趣,例如三角形:http://oeis.org/A047920。 还有一篇文章提到那里:http://www.pmfbl.org/janjic/enumfun.pdf,也许它可以帮助,如果你有兴趣在n
和m
通用封闭公式。突然之间,我没有任何想法想出来,但我认为这可能是一个很好的起点。
这个问题的另一个可能的目的地是http://crypto.stackexchange.com/(尽管检查他们的帮助部分是肯定的)。 –
在发布完整答案之前,只有两条简短评论:!11不是39916800,而是5!* 6!只是正确结果的一个子集,因为这两个群体可以“混合在一起”,而不仅仅是独立排列。 – elias
对不起,这是一个错字,11! = 39916800,!11 = 14684570 - 我会修改它..你如何表达这两个组合“混合在一起”?我认为这是我没有得到的部分..感谢您的回复 – guskenny83