1 条题解
-
0
题目大意
给定 个字符串,求有多少个子集满足:子集中恰好有 对字符串互为变位词(即可以通过重新排列字母得到彼此)。
解题思路
关键观察
- 变位词分组:互为变位词的字符串具有相同的字母组成
- 配对计数:如果从同一组中选取 个字符串,会产生 对变位词
- 独立计数:不同组之间的选择是独立的
算法步骤
1. 字符串哈希分组
// 使用随机权值计算字符串的"字母组成指纹" for (int j = 0; j < 26; ++j) a[i] += cnt[j] * val[j]; ++mp[a[i]];2. 动态规划计数
定义
f[i]表示产生恰好 对变位词的方案数。对于每组大小为 的变位词组:
- 如果选择 个字符串,会产生 对变位词
- 从 个字符串中选 个的方案数为
状态转移:
for (int i = k; ~i; --i) if (f[i]) for (int j = t; j; --j) if (i + j * (j - 1) / 2 <= k) add(f[i + j * (j - 1) / 2], 1ll * f[i] * C(t, j) % mod);3. 组合数预处理
使用逆元预处理组合数,支持快速计算 。
复杂度分析
- 时间复杂度:,其中 是字符串最大长度
- 空间复杂度:
总结
本题通过变位词分组+动态规划计数的经典组合,将复杂的子集计数问题转化为分组背包问题。关键在于发现同一组内选择 个字符串会产生 对变位词,从而可以独立计算每组对总配对的贡献。
- 1
信息
- ID
- 4834
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 6
- 已通过
- 1
- 上传者