【tdpcO】
题面
问有多少个字符串满足仅有小写字母组成,且 a a a ~ z z z 各恰好出现 f 1 f_1 f1 ~ f 26 f_{26} f26 次,且没有相邻两个字母相同。答案对 1 0 9 + 7 10^9 + 7 109+7 取模。
f i ≤ 10 f_i \leq 10 fi≤10
题解
令 d p i , j dp_{i,j} dpi,j 为使用了前 i i i 种字母,有 j j j 个位置不合法的方案数。转移时可以枚举当前字母被分成了几段插入,方案是组合数;同时能得出当前字母产生的新的不合法方案数。然后可以枚举有几段被插入到了不合法位置,方案又是组合数。剩余的各种情况都可以用组合数计算。
时间复杂度 O ( ∑ f i ∗ ∑ f i 2 ) O(\sum f_i * \sum f_i^2) O(∑fi∗∑fi2)
【同类活用】
题面
n n n 个数,问形成的排列里面任意相邻两个数相乘均不是完全平方数的方案数
n ≤ 300 n \leq 300 n≤300,值域 [ 1 , 1 0 9 ] [1,10^9] [1,109]
题解
初看上去似乎和上题没什么关系,但是也不知道怎么做。
考虑一个基本性质:
若 a b ab ab 是完全平方数, b c bc bc 也是完全平方数,则 a c ac ac 是完全平方数。
证明很 trivial。
定义两数间关系 x x x:两数相乘得完全平方数,由上可见 x x x 具有自反性与传递性。
则我们必能把原来的 n n n 个数分成若干个不相交集合,每个集合内要么只有一个数,要么任意两数间满足关系 x x x,且不同集合之间不能取出两个数使得它们之间具有关系 x x x。
给集合编号。令 d p i , j dp_{i,j} dpi,j 表示只用前 i i i 个集合的数凑成排列,有 j j j 个位置出现相邻两数满足性质 x x x 的方案数。那就跟 tdpcO 一模一样了。
本质上就是:同属一个集合的数等价于 tdpcO 中相同的字母。
时间复杂度极限情况下 O ( n 3 ) O(n^3) O(n3)。
【总结】
考虑排列与相邻不合法这类问题时,可以多考虑插入法设立状态,并分类建立不合法关系集合,用组合数计算答案。要深入挖掘题目的性质!!!