n 个人围绕着圆桌坐着,其中一些是男孩,另一些是女孩。你的任务是找出所有合法的方案数,使得不超过 k 个女孩座位是连续的。循环同构会被认为是同一种方案。 数据组数 T<=50, n, k<=2000
【20%】n,k<=20
暴力还是有点麻烦。 主要思想就是用最小表示法来去重。 不多说了。。。
【100%】n,k<=2000
模型是burnside的经典模型。。。 对于第 i 个置换(0<=i<=n-1),只有开头的 d=gcd(i,n) 个位置的颜色选择是自由的,然后把这一段复制 n/d 份构成完整序列。
看看这个 d 个位置有什么限制?1、连续的女孩(用0表示)不超过 k 个;2、开头连续的 0 加上末尾连续的 0 不超过 k 个,这是因为把这一段复制之后要头尾拼接。
直接在 d 个位置上dp不好搞,因为要维护头尾的 0 加起来不超过 k 个。所以设 $f[k][i]$ 表示:我搞 i 个位置出来,这 i 个位置头尾都是 1,其内部连续的 0 不超过 k,的方案数。(实际dp中第一维可以去掉) 这个dp很好搞,对于 i 枚举上一个 1 放在哪里就行了,这是O(n)的。
回到题目,我现在要 d 个位置,那我们可以枚举 i,相当于枚举了 d 个中的一段,然后我们在前后补 0,总共补 d-i 个0。所以 i 的贡献就是 $f[k][i] \times (d-i+1)$。这里我们可以看出维护一个 f 的前缀和以及一个 f×i 的前缀和就行了。 头尾加起来 <=k 就相当于 d-i<=k。如果上面用前缀和的话,减掉不合法的就行了。