AOJ2025 Eight Princes

本文探讨了特定条件下的人群排列问题,给出了奇数和偶数情况下不同的解决方案,并通过Python实现了解题算法。

我们查看更一般的情况,设人数为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

 

转载于:https://www.cnblogs.com/rausen/p/4335804.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值