原题链接
1 题目
1.1 题目所需求出内容
对于本题,最终要求:一个具体值
1.2 题目背景、允许、禁止与限制
背景:
有一个单词集合 SSS
允许:
一组单词是安全的,当且仅当不存在一个单词是另一个单词的前缀
求这个集合中有多少集合使得里面所有单词都互相安全,空集永远是安全的
1.3 题目数据范围与猜测
O(n4)O(n^4)O(n4)
1.4 一句话概括题意
有一个字符串集合,求这个集合中有多少集合使得里面所有字符串都互相安全,空集永远是安全的
2 题目破题推导
2.1 第一步:数学思考与证明(反证法)
思考单调性:
把所有字符串按字典序排序后,如果对于一组字符串 i,j,ki,j,ki,j,k 使得 j<i,k<jj < i,k < jj<i,k<j 且均不为前缀,则 kkk 对于 iii 一定不为前缀
证明:
假设存在一组字符串 i,j,ki,j,ki,j,k 使得 k<j<ik < j < ik<j<i 且均不互为前缀,但 kkk 为 iii 的前缀。
那么就说明 iii 的开头一部分完全等于 kkk
发现 k<jk < jk<j 说明在某一位会出现 ki<jik_i < j_iki <ji
那么由于 iii 的开头一部分完全等于 kkk,会出现 ii<jii_i < j_iii <ji ,因此 i<ji<ji<j
但是这时与求证定义矛盾,因此可以证明把所有字符串按字典序排序后,如果对于一组字符串 i,j,ki,j,ki,j,k 使得 j<i,k<jj < i,k < jj<i,k<j 且均不为前缀,则 kkk 对于 iii 一定不为前缀
2.2 第二步:边界意识
因为这里面说了“空集永远是安全的”,因此记录的时候要始终多加 111 代表空集
还有因为 n≤50n\le 50n≤50,因此选择的可能性(集合的组合)是 2502^{50}250
3 模型匹配
那就是一个很简单的dp,这里由于是所有方案可能性都要考虑到,所以要注意初始化和累加
4 最终代码(禁止抄袭,仅用于参考)