状态压缩DP

有集合SSS=n|S|=n,则有TS2T=k=0n2k(nk)=3n\sum\limits_{T \subseteq S}2^{|T|}=\sum\limits_{k=0}^{n}2^k\dbinom{n}{k}=3^n。因此,若我们枚举集合,枚举集合的子集的子集做状压DP时,可以得到正确的复杂度O(3n)\mathrm{O}(3^n)而非错误的O(2n×2n)=O(4n)\mathrm{O}(2^n\times 2^n)=\mathrm{O}(4^n)。参见AtCoder ABC 187 F – Close Group

可以这样证明:考虑某个子集的子集PTSP \subseteq T \subseteq S,则SS中的每个元素有三种状态:aPa\in PaP,aTa \notin P, a \in TaT,aSa \notin T, a \in S。显然这样可以唯一表示SSTT以及PP,对应了所有子集的拆分方案。故原式成立。

More
  • 2022年2月24日

Problem D – Codeforces Round #127 (Div. 1)

多模式串匹配,是不是又是AC自动机啊?

显然,每个文本串中,模式串的排列构成的子序列的逆序对数量只和模式串有关。所以我们可以对模式串建立Trie树,每扫入一个文本串的单词就进行匹配。可以做到O(K)\mathrm{O}(K),K为文本串总长(虽然单个字符串的长度极小可以O(NK)暴跳\mathrm{O}(NK)暴跳)。这样就构建出一个由11nn构建的数列。

枚举15!15!的全排列然后暴搜显然不可行。我们注意到,如果钦定一个数xx,只要知晓当前的排列中前jj位分别是哪些数,就可以立刻算出xx加入排列后新增的逆序对数量。则我们考虑状压DP。 (更多…)

More
  • 2021年10月12日