我们查看更一般的情况,设人数为m

则n < m * 2无解

然后n为奇数的情况:

我们把一个人和一个空格打包,于是剩下m个"人"和n - m个空格,随便排列这些"人",然后把空格插入

本质不同的"人"的圆周排列有(m - 1)!个,对于每个排列,有m个位置插入n - m个空格,有C(n - m - 1, m - 1)中方法,然后对于一个排列,圆周排列有n个

ans = C(n - m - 1, m - 1) * (m - 1)! * n

最后是n为奇数的情况:

我们把相对的两个点打包,然后就变成一个长度为n / 2的圈

等价于n / 2中选m个,一个有k段连续的1的方案对应原来的2k种方案

于是ans = n / 2 * (m - 1)! * Σ (2k * C(n / 2 - m - 1, k - 1) * C(m, k)) (其中1 ≤ k ≤ m)

然后题目比较鬼畜。。。我还是上py好了。。。

 

 1 def C(n, m) :
 2     if (n < m) : return 0
 3     return fac[n] / fac[m] / fac[n - m]
 4  
 5 def work_odd(n, m) :
 6     return n * C(n - m - 1, m - 1) * fac[m - 1]
 7  
 8 def work_even(n, m) :
 9     res = 0
10     n /= 2
11     i = m
12     while (i > 0) :
13         res = (res + C(n - m - 1, i - 1) * C(m, i)) * 2
14         i -= 1
15     return res * fac[m - 1] * n;
16  
17 fac = [1] * 105
18 for i in range(1, 100) : fac[i] = fac[i - 1] * i
19 n = input()
20 m = 8
21 while (n > 0) :
22     if (n < m * 2) : print 0
23     elif (n % 2 == 1) : print work_odd(n, m)
24     else : print work_even(n, m)
25     n = input();
View Code

 

posted on 2015-03-13 19:08  Xs酱~  阅读(226)  评论(0编辑  收藏  举报