提高组 dp 专题 4 做题记录
提高组 dp 专题 4 做题记录
- 带
*表示未做出,带^表示半做出。
*A [PA2021] Od deski do deski
这个题的难点在于设计状态。首先明确这道题不是区间 dp,因为不同的区间答案显然一致。所以考虑对每一个长度 dp。接下来进一步考虑,我们对于一个位置 \(i\),选的数如果要合法,那么前面必然存在一个 \(a_j=a_i\),且 \([1,j-1]\) 合法。
对于考虑之前贡献的题目,不难想到提前计算。设 \(f(i,j)\) 表示长度为 \(i\) 的序列,当前共有 \(j\) 种 \(a_x\) 满足上述合法要求,且 \([1,i]\) 合法方案数;\(g(i,j)\) 表示的是 \([1,i]\) 不合法方案数。按照上述过程转移即可。
B [TJOI2019] 甲苯先生的字符串
简单矩阵快速幂即可。
C [ABC213G] Connectivity 2
考虑正难则反,用总数减去两者不联通方案数。对于不联通方案数,可以枚举 \(1\) 所在联通块点集,并使其不包含 \(x\),然后求出使这部分点集联通的方案数再乘剩下点集之间任意连边方案数即可。
至于怎样求使一部分点集联通的方案数,利用经典的图上容斥计数套路即可。
*D 某位歌姬的故事
首先考虑 \(m_i=2,A=2\) 怎么做。实际上就是说要在序列上选一些点,使得给定的每个区间内都有一个点。显然可以利用 dp,设 \(dp(i,j)\) 表示在前 \(i\) 个位置中选,且最后一个点选在 \(j\) 的方案数。转移按照 \(i\) 选不选的情况讨论即可。为了满足区间限制,我们对每一个 \(r\) 求出所有询问中最大的 \(l\)。当我们来到一个 \(r\) 时,就要将所有 \(j<l\) 的 dp 值赋为 \(0\)。
然后考虑正解。首先将区间离散化,变成若干个点。接着对每一个点求出包含他的询问中 \(w\) 的最小值,则最后这个点必然只能选 \(\le minw\) 的数,且最后也只能对 \(w=minw\) 的要求做出贡献。因此,我们实际上可以将所有要求按照 \(w\) 拆开,每一个 \(w\) 都有对应为他做出贡献的位置,这样问题就和上面一样了。
当然现在复杂度是 \(O(Q^2)\) 的,利用线段树优化上述 dp 过程,可以做到 \(O(Q \log Q)\) 的复杂度。
*E [ABC134F] Permutation Oddness
考虑将位置和数值拆开,然后就是对它们进行配对。配对问题的一种经典做法就是记录前面有多少个位置还没有配上,进而计算贡献。此题同理,设 \(dp(i,j,k)\) 表示考虑前 \(i\) 个数,数值和位置分别有 \(j\) 个位置没有配上(显然两者数量相同),怪异度为 \(k\) 的方案数。根据当前枚举到的数值和位置是向后配对还是向前配对转移即可。
F [JSOI2018] 潜入行动
简单树形背包。设 \(dp(i,j,0/1,0/1)\) 表示 \(i\) 子树内放了 \(j\) 个监测点,且该节点被 / 不被检测、放 / 不放监测点的方案数。
*G [TJOI2018] 游园会
dp 套 dp 的板子,完全不会直接颓。
*H [AGC035D] Add and Remove
不难想到最后的答案是 \(\sum x_ia_i\) 的形式,则 \(x_i\) 就是每个数的贡献系数。
显然考虑区间 dp。考虑区间 dp 的一种处理方式:反向思考最后一步操作的影响。假设最后删除的是 \(a_i\),那么它的贡献系数就是 \(x_1+x_n=2\)。按照这样的考虑方式,假如我们当前我们要将 \(a_x\) 和 \(a_y\) 中间的数删掉,它的贡献系数就是 \(x_x+x_y\)。
依照这样的方式,我们可以设 \(dp(l,r,x,y)\) 表示将 \((l,r)\) 区间删完后的贡献总和(不包括 \(l,r\)),于是就可以按照上面的方式去枚举这个区间最后删掉的数 \(p\),转移即为:
由于 \(n\) 只有 \(18\),因此可以直接搜索得出答案,复杂度 \(O(3^n)\)。
(实际上模拟退火对于本题都可以得到较高分数)
^I [HNOI2015] 实验比较
首先考虑对有相等要求的画缩点,然后对于限制 \(x<y\),连边 \(x\to y\)。这样就形成了一颗森林。现在问题就类似于求森林的拓扑序。
首先建立超级源点,将每一颗树连起来。接下来考虑 dp,发现困难的地方在于 \(=\) 的限制。因此设 \(dp(x,i)\) 表示 \(x\) 子树的拓扑序被 \(i-1\) 个 \(<\) 分成 \(i\) 段的方案数。利用树形背包的方式转移即可。
现在的问题实际上是如何将 \(j\) 段的序列和 \(k\) 段的序列合成 \(i\) 段的序列(其中 \(i,j\) 段序列的第一段一定都是单独的 \(x\))。考虑先将剩下的 \(j-1\) 段填入 \(i-1\) 段中;接着除掉剩下的 \(i-j\) 段,我们还要选 \(k-(i-j)\) 段来填剩下的段。因此方案数为:
最后输出 \(\sum dp(n+1,i)\) 即可。复杂度 \(O(n^3)\)。
*J [POI2014] Hotel
考虑枚举三个点到根节点的路径交点处,接下来考虑求答案。设 \(f(x,i)\) 表示 \(x\) 子树内距离 \(x\) 为 \(i\) 的点的个数,再设 \(g(x,i)\) 表示 \(x\) 子树内有多少个点对 \((u,v)\),满足 \(dis(lca(u,v),u)=dis(lca(u,v),v)=dis(lca(u,v),x)+i\)。
转移方程并不难想,最后答案也可以由两个 dp 数组推出。现在的问题在于上述枚举过程是 \(O(n^2)\) 的,无法通过加强版。考虑到状态中有与深度有关的状态,因此可以长链剖分优化 dp,将复杂度化为 \(O(n)\) 即可通过。

浙公网安备 33010602011771号