正能量的dp——状压/容斥
总结
容斥
这部分的容斥主要是 DAG 上的,本质上是子集反演。基本上就是枚举一层的点集合,然后根据实际情况计算系数。
题目
P6846
首先发现将一张 DAG 的边全部反向,仍然是一张 DAG。并且这两种改边总和是 \(m\)。所以答案就是 \(m\) 乘定向 DAG 方案数除以二。
考虑一个 DAG 的特征,考虑剖成若干层入度为 \(0\)。这启发我们考虑一种计数,设 \(f_{S}\) 表示 \(S\) 是 DAG 的方案数,转移就找到一层,则要求这一层显然是一个独立集。所以
发现这样显然会算重,因为可能 \(S\setminus T\) 还有 \(0\) 入度点,所以设 \(F(A)\) 表示钦定 \(A\) 是独立集的算出来的系数即 \(f_{S\setminus A}2^{E_{A\to S\setminus A}}\),\(G(A)\) 表示独立集恰好是 \(A\) 的方案数,所以有
相当于只需在原本的式子上乘上一个 \((-1)^{|T|+1}\) 的系数。或者直观理解就是容斥原理。\(A\cup B=A+B-A\cap B\)。所以时间复杂度 \(O(3^n)\)。
A
首先如果原图不是一个 SCC,那么缩点之后就是一个 DAG。所以这个题跟上一题有很大的相似之处。
设 \(f_{S}\) 表示 \(S\) 不是强联通的方案数,相当于就是缩点后是 DAG。那么跟上题一样,枚举一个集合,由于你不知道它缩点后有几个独立集,所以再设 \(g_{S,i}\) 表示 \(S\) 缩点后是 \(i\) 个独立集的方案数,那么类似上道题有
其中 \(2^{E\setminus T}\) 是因为这个集合里的边是可以乱连不用保证是一个 DAG 的,因为 \(S\) 一定不是一个 SCC。
然后这个转移是有点问题的,当 \(T=S\) 时会多算 \(g_{T,1}\),而这个相当于 \(S\) 是一个 SCC 了,所以不能算上。并且 \(g_{S,1}=2^{E_S}-f_S\),需要算出 \(f_S\) 才能求出,所以避免了自转移的情况。\(g_{S,i\ge 2}\) 是好求的。
然后时间复杂度就是 \(O(3^nn)\) 了,但是注意到可以直接将 \((-1)^{i+1}\) 系数记进 \(g_{T}\),于是就做完了。
\(\color{red}-\) 是 \(-1\) 的系数。
E
答案显然不会超过 \(n\)。考虑怎么用操作二节省次数。容易发现一定是若干集合 \(S\) 使用 \(|S|-1\) 次操作二变成全 \(0\),因为如果 \(\ge |S|\) 不如全用操作 \(1\),\(<|S|-1\) 一定可以继续拆。然后剩下的数使用操作一变成 \(0\)。
为了让答案最小,即让这样的 \(S\) 最多。考虑将操作二的两个数连边以刻画操作,那么根据上面的结论一定是 \(S\) 是树时最优。先考虑怎样的 \(S\) 是合法的。
先考虑弱化问题,每次选两个数 \(-x\),随便钦定一个点作为树的根,那么考虑剥叶子,只需要最终根的权值为 \(0\) 即可。发现奇数层的对根的贡献为 \(+\),偶数层的贡献为 \(-\),于是奇数层的权值和与偶数层的权值和相等是 \(S\) 合法的充要条件。进一步,这个等价于找到一个子集 \(T\),使得 \(T\) 的权值和等于 \(S\setminus T\) 的权值和,因为是一定能还原成一棵树的。
现在变成一个 \(-x\) 一个 \(-x-1\)。相当于在刚刚基础上,再执行 \(|S-1|\) 次操作,每次让奇数层或者偶数层的权值 \(+1\),然后最终权值和相等。形式化的就是找到子集 \(T\) 使得 \(|s(T)-s(S\setminus T)|\le |S|-1\) 并且 \(|s(T)-s(S\setminus T)|\equiv |S|-1\pmod 2\),因为更改一次操作差就会变化 \(2\)。也即 \(s(S)\equiv |S|-1\pmod 2\)。
那么判合法时间复杂度就是 \(2^{|S|}\),对于所有 \(S\) 判就是 \(3^n\),常数有点大考虑优化。比较经典的就是折半,将两边排序后就可以双指针扫一遍了,问题在于排序,是 \(O(\sqrt 2^{|S|}|S|)\) 的,然后发现考虑每次往集合加入一个数,是可以归并排序的,所以就去掉了 \(|S|\),总时间复杂度就是 \(\displaystyle\sum_{i=0}^{n}\binom{n}{i}\sqrt 2^i=(\sqrt 2+1)^n\)。
然后就基本上做完了,直接做一遍 \((\max,+)\) 子集卷积就可以算出最多 \(S\) 的数量,是一个常数小的 \(3^n\),所以就能通过了。当然也可以倍增+子集卷积做到 \(O(2^nn^2\log n)\),意义不大。
技巧:
- 子集折半。
- 二元组考虑建图。
- 奇偶分层。
C
首先答案显然是不会超过值域的。然后分析一下,如果确定了回应观众的集合,那么最优策略肯定是,选择当前 \(B\) 中 \(\le a_i\) 的最大数替换成 \(a_i\),如果不存在就新加一个元素。或者也可以将原问题用 Dilworth 变成划分最少的不降子序列。
发现 \(B\) 中元素一定是互不相同的。于是便能设计出一个 dp,\(f_{S,i}\) 表示当前 \(B\) 元素组成集合为 \(S\),考虑前 \(i\) 个并钦定第 \(i\) 个观众回应是否可行,于是便能做到 \(O(2^Vn)\)。
\(f_{S,i}\) 值域只有 \(0,1\),所以考虑交换状态和值域,事实上最终答案只关心有哪些 \(f_{S,n/n-1}=1\),所以只需要关注 \(S\) 能到最远的 \(i\)。即设 \(g_{S}=\max\limits_{f_{S,i}=1}i\)。
然后发现转移有自环,即如果当前 \(g_S=p\),如果 \(a_{p+1}\in S\),那么可以继续拓展;否则如果 \(a_{p+2}\in S\),也是可以继续拓展的。因为新到的 \(S'\) 是等于 \(S\) 的。所以只需找到最小的 \(a_i,a_{i+1}\not \in S\) 的 \(i\),可以通过一些方法做到 \(O(2^VV^2+nV)\),但这不是重点。
- 交换值域与状态。
F
考虑对于一个选取的集合 \(S\),假设能让只选 \(S\) 合法的最大长度是 \(f_S\),那么显然其合法的长度就是 \(\left[\sum_{i\in S}a_i,f_S\right]\) 这个区间,可以通过调整得到。于是只要求出 \(f_S\),便能求出答案。
相当于有一个集合 \(T\) 不能选,如果我们直接设状态 \(f_S\) 表示选取的数是 \(S\),不能选的是 \(\complement_U S\),发现假设当前要选 \(i\in S\),相当于 \(S\) 就被分成了两个部分,即放 \(i\) 左边的 \(S_1\) 和右边的 \(S_2\)。发现 \(S_1\) 在选的过程中只是要求不能选 \(\complement_U S\) 而非 \(\complement_U S_1\),所以这个做法就有问题。
所以就要记 \(f_{i,S,T}\) 表示要选 \(S\) 里的数,不能选 \(T\) 里的数所占据的最长长度,当前考虑的数是 \(a_i\),分情况考虑一下
- \(i\in T\),那么 \(f_{i,S,T}=\min(a_i-\epsilon,f_{i+1,S,T})\),这是因为 \(i\) 要先放,如果长度 \(\ge a_i\) 就不合法了。
- \(i\in S\),那么 \(f_{i,S,T}=a_i+\displaystyle\max_{S_1\cup S_2=S\setminus \{i\}}\left\{f_{i+1,S_1,T}+f_{i+1,S_2,T}\right\}\)。
- 否则不用管,\(f_{i,S,T}=f_{i+1,S,T}\)。
考虑 \(\epsilon\) 的问题,注意到最后答案一定是一个左闭右开区间,所以不需要管,最后让 \(f_S>m\) 就行了。
- 观察划分产生的子问题。

浙公网安备 33010602011771号