我们查看更一般的情况,设人数为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();
时间: 2024-10-26 05:28:22