首先,请注意,您可能会忽略将火车从进站直接移动到出站的可能性:可以通过将火车移动到支线然后再离开来完成这种移动。
表示一列火车从输入到支线 as(
和一列火车从支线到输出 as )
,你会得到火车的排列和 n 对正确平衡括号的字符串之间的双射。该陈述需要证明,但证明中唯一困难的部分是证明没有两串平衡括号对应于相同的排列。此类字符串的数量是第 n 个加泰罗尼亚数,或 choose(2n, n)/(n+1),其中choose(n, k) 是从 n 中选择 k 个项目的方式数。
这是计算解决方案的代码:
def perms(n):
r = 1
for i in xrange(1, n+1):
r *= (n + i)
r //= i
return r // (n + 1)
您可以使用此代码生成所有排列,这也暴露了解决方案的加泰罗尼亚语性质。
def perms(n, i=0):
if n == 0:
yield []
for k in xrange(n):
for s in perms(k, i+1):
for t in perms(n-k-1, i+k+1):
yield s + [i] + t
print list(perms(4))
输出:
[[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], [0, 2, 3, 1],
[0, 3, 2, 1], [1, 0, 2, 3], [1, 0, 3, 2], [1, 2, 0, 3],
[2, 1, 0, 3], [1, 2, 3, 0], [1, 3, 2, 0], [2, 1, 3, 0],
[2, 3, 1, 0], [3, 2, 1, 0]]