CF1082F - Speed Dial
CF1082F - Speed Dial
题目大意
给定 \(n\) 个电话号码,你可以随意生成 \(k\) 个快捷键,每个快捷键是一个数字串
最终拨号方式:
选择 至多一个 快捷键按下,对于剩余部分手动补全,且不允许退格
每个电话号码有拨打次数,最小化手动补全部分的长度总和
分析
如果每次选定一个集合使其公用一个快捷键,那么其长度必然是集合中所有串的 \(\text{LCP}\)
假设确定了一个 \(\text{LCP}\) ,那么对应的串集合容易发现就是 \(\text{trie}\) 树上的一个子树
于是先将所有串加入 \(\text{trie}\) 树,此时问题转化为
选择至多 \(k\) 个 \(\text{LCP}\) (默认根节点选了且没有代价),使得每个电话号码到其祖先中最深 \(\text{LCP}\) 的距离之和最小
由于有拨打次数的限制,且其数值相对较大,难以存入dp状态
于是想到在祖先钦定 \(\text{LCP}\) ,然后从子树取值
令 \(dp_{u,i,j}\) 表示计算 \(u\) 子树内的答案,已经钦定祖先中最深的 \(\text{LCP}\) 长度为 \(i\) ,且在子树内又钦定了 \(j\) 个 \(\text{LCP}\)
合并子树时对于每个 \(i\) ,背包合并 \(j\) ,决策 \(u\) 自己是否选为 \(\text{LCP}\) 即可
1 |
|