假设我们有 n 元素, a 1 , a 2 , ..., a n ,排成一个圆圈。也就是说, a 2 介于 a 1 和 a 3之间, a 3 介于 a 2 和 a 4 , a n 介于 a n -1 和 a 1 ,等等。
每个元素可以取1或0的值。如果有相应的 a i 的值,则两个排列不同不同。例如,当 n = 3时,(1,0,0)和(0,1,0)是不同的排列,即使它们在旋转或反射下可能是同构的。
因为有 n 元素,每个元素都可以取两个值,所以排列的总数是2 n 。
以下是问题:
可能有多少种安排,这样两个相邻的元素都没有值1?如果有帮助,只考虑 n > 3的情况。
我问这里有几个原因:
答案 0 :(得分:10)
让我们首先问一个问题“有多少0-1个长度为n的序列,没有两个连续的1?”让答案是A(n)。我们有A(0)= 1(空序列),A(1)= 2(“0”和“1”),A(2)= 3(“00”,“01”和“10”但是不是“11”)。
为了更容易编写重复,我们将A(n)计算为两个数字的总和:
B(n),以0结尾的这种序列的数量,和
C(n),以1结尾的此类序列的数量。
然后B(n)= A(n-1)(取任何长度为n-1的序列,并附加0)
和C(n)= B(n-1)(因为如果在位置n处有1,则在n-1处必须为0。)
这给出A(n)= B(n)+ C(n)= A(n-1)+ B(n-1)= A(n-1)+ A(n-2)。
到现在为止应该很熟悉: - )
A(n)就是Fibonacci数F n + 2 ,其中Fibonacci序列由
F 0 = 0,F 定义1 = 1,F n + 2 = F n + 1 + F n ,n≥0。
现在提出你的问题。我们将分别计算 1 = 0和 1 = 1的排列数。对于前者, 2 ... a n 可以是任何序列(没有连续的1),因此数字是A(n-1)= F n + 1个子>。对于后者,我们必须有一个 2 = 0,然后一个 3 ... a n 是没有连续1的任何序列以0 结束,即B(n-2)= A(n-3)= F n-1 。
所以答案是F n + 1 + F n-1 。
实际上,我们可以比那个答案更进一步。请注意,如果您将答案称为
G(n)= F n + 1 + F n-1 ,则
G(n + 1)= F n + 2 + F n ,和
G(n + 2)= F n + 3 + F n + 1 ,因此即使G(n)也满足与Fibonacci序列相同的复发! [实际上,Fibonacci类序列的任何线性组合都会满足同样的复发,所以并不是那么令人惊讶。]所以计算答案的另一种方法是使用:
G(2)= 3
G(3)= 4
n≥4时G(n)= G(n-1)+ G(n-2)。
现在你也可以使用closed form F n =(α n -β n )/(α- β)(其中α和β为(1±√5)/ 2,x 2 -x-1 = 0)的根,得到
G(n)=((1 +√5)/ 2) n +((1-√5)/ 2) n 。
[你可以忽略第二项,因为对于大n,它非常接近0,实际上G(n)是最接近的整数((1 +√5)/ 2) n < / strong>所有n≥2。]
答案 1 :(得分:1)
我决定修改一个小脚本来尝试一下:
#!/usr/bin/python
import sys
# thx google
bstr_pos = lambda n: n>0 and bstr_pos(n>>1)+str(n&1) or ""
def arrangements(n):
count = 0
for v in range(0, pow(2,n)-1):
bin = bstr_pos(v).rjust(n, '0')
if not ( bin.find("11")!=-1 or ( bin[0]=='1' and bin[-1]=='1' ) ):
count += 1
print bin
print "Total = " + str(count)
arrangements(int(sys.argv[1]))
为5运行这个,给了我总共11个可能性00000, 00001, 00010, 00100, 00101, 01000, 01001, 01010, 10000, 10010, 10100
P.S。 - 请原谅上面代码中的not()。
答案 2 :(得分:0)
把我天真的脚本扔进混合物中。很多机会可以缓存部分结果,但是对于小n来说它运行得足够快,我没有打扰。
def arcCombinations(n, lastDigitMustBeZero):
"""Takes the length of the remaining arc of the circle, and computes
the number of legal combinations.
The last digit may be restricted to 0 (because the first digit is a 1)"""
if n == 1:
if lastDigitMustBeZero:
return 1 # only legal answer is 0
else:
return 2 # could be 1 or 0.
elif n == 2:
if lastDigitMustBeZero:
return 2 # could be 00 or 10
else:
return 3 # could be 10, 01 or 00
else:
# Could be a 1, in which case next item is a zero.
return (
arcCombinations(n-2, lastDigitMustBeZero) # If it starts 10
+ arcCombinations(n-1, lastDigitMustBeZero) # If it starts 0
)
def circleCombinations(n):
"""Computes the number of legal combinations for a given circle size."""
# Handle case where it starts with 0 or with 1.
total = (
arcCombinations(n-1,True) # Number of combinations where first digit is a 1.
+
arcCombinations(n-1,False) # Number of combinations where first digit is a 0.
)
return total
print circleCombinations(13)
答案 3 :(得分:0)
此问题与Zeckendorf representations非常相似。由于圆度约束,我找不到一种明显的方法来应用Zeckendorf定理,但Fibonacci数在这个问题中显然非常普遍。