动态规划泛做

CF833B The Bakery

\(f_{i,k}\) 表示前 \(i\) 个数字分成 \(k\) 段的最大总价值,显然有暴力转移 \(f_{i,k}=f_{j,k-1}+kind(j+1,i)\),其中 \(kind(x,y)\) 表示 \([x,y]\) 中不同数字的种数。

但暴力转移是 \(O(n^2k)\) 的,考虑把 \(kind\) 函数拆开优化,把每种数字的贡献对应到区间中该种数字第一次出现的位置。对于数字 \(a_i\),其对 DP 数组产生贡献的范围是 \([pre_i,i)\),这部分转移过来能得到没出现过的数字 \(a_i\)

先枚举 \(k\),再枚举 \(n\),用线段树维护上一轮的 DP 数组加上转移的贡献,前缀 \(\max\) 即为当前 DP 值。

CF449D Jzzhu and Numbers

发现直接统计按位与为某个值的方案数非常困难,考虑先统计出按位与包含某个值的方案数,即按位与为该值的超集的方案数,然后差分回去(做系数为 \(-1\) 的超集高维前缀和)即可得到按位与为某个值的方案数。

按位与包含某个值的方案数很好计算,不包含该值的数不能选,包含的可选可不选,但至少选一个。做超集高维前缀和然后快速幂计算即可。

CF123E Maze

先考虑固定起点和终点怎么做,我们必须依次经过路径上的每一条边。假如当前在 \(u\) 要通过 \((u,v)\) 走向 \(v\),那么有概率会先通过 \((u,v')\) 走到 \(v'\)。当完全遍历完\(v'\) 为根的子树后,我们会退回来,再次选择一条边走。因为选择是随机的,所以 \(v'\)\(v\) 之前被选择到的概率是 \(\frac{1}{2}\),另外 \(\frac{1}{2}\) 会先进入 \(v\) 然后不出来了。

仔细观察一下伪代码,搜下去没有找到会加两次,也就是说除了路径上的边,贡献均为 \(1\);而路径上的边是必定经过的,贡献恰好也为 \(1\)。那么问题就转化成了以起点为全树的根,去掉以终点为根的子树,剩下的点或边的期望数量。

随便钦定一个点作为全树的根,然后枚举终点,对起点分是否在以终点为根的子树中讨论,简单计算一下就好了。

P1285 队员分组

将没有互相认识的两人连边,这样有边相连的两人就不能放进同一组。发现每个连通块是独立的,对每个连通块都跑一遍二分图染色,一旦出现冲突就说明不存在合法方案。最后跑一遍带方案的必选背包。

P2519 [HAOI2011] problem a

如果 \(a_i+b_i\geq n\),那么第 \(i\) 个人一定在说假话。

否则说明 \((b_i,n-a_i]\) 这段排名区间中的人成绩是相同的,并且这个成绩也只出现在这段排名区间中,所以我们可以按成绩一段一段 DP。

预处理出每种排名区间的数量即可,注意数量大于区间长度时多出来的那些人肯定说了假话,要取个 \(\min\)

P2476 [SCOI2008] 着色方案

观察到 \(c\) 很小可以记入状态,令 \(f_{a,b,c,d,e,last}\) 表示还可以涂 \(1/2/3/4/5\) 个木块的颜色有 \(a/b/c/d/e\) 种,上一次涂的颜色还能涂 \(last\) 次的方案数。

虽然能过,但这样实在是太不优秀了。我们其实没必要按木块顺序涂色,完全可以按颜色顺序用插入的形式转移。令 \(f_{i,j}\) 表示前 \(i\) 个木块,有 \(j\) 处相邻同色木块的方案数。

主动转移,枚举当前颜色分成的段数 \(a\) 和其中插入相邻同色木块的段数 \(b\)

\[f_{i+1,j-b+c_{i+1}-a}\gets f_{i+1,j-b+c_{i+1}-a}+f_{i,j}\times\binom{c_{i+1}-1}{a-1}\times\binom{j}{b}\times\binom{sum_i+1-j}{a-b} \]

其中 \(sum\) 表示 \(c\) 的前缀和。第二维的意思是原先有 \(j\) 处,加入新相同的 \(c_{i+1}-a\) 处,破坏掉原先相同的 \(b\) 处。

三个组合数的意思是隔板法算分段方案数;插入相邻同色木块的方案数;插入相邻不同色木块的方案数。

P2523 [HAOI2011] Problem c

显然有解的条件就是所有后缀中的人数不能超过后缀长度,注意要在一开始判,因为最终方案数是取模过的。

因为较短的后缀会影响到较长的后缀,所以从后往前 DP,令 \(f_{i,j}\) 表示大于 \(i\) 的编号已经确定,其中有 \(j\) 个人没有贿赂上司的方案数。

转移就直接枚举当前编号 \(i\) 安排了 \(k\) 个没有贿赂上司的人,其中 \(k\) 的合法范围就是 \(n-i+1-j\) 再减去后缀中贿赂过上司的人数。现在还有 \(n-m-j\) 个人没有确定过编号,因为人是不同的,所以要乘上组合数:

\[f_{i-1,j+k}\gets f_{i-1,j+k}+f_{i,j}\times\binom{n-m-j}{k} \]

CF559C Gerald and Giant Chess

黑色格子比较多显然不能容斥,那就需要给每种不合法或者每种合法的方案定一个唯一的标识,在标识处进行计算。

\(f_i\) 表示从 \((1,1)\) 走到第 \(i\) 个黑色格子,不经过其它黑色格子的方案数。转移就拿不考虑黑色格子的总方案数减掉上一次从黑色格子来的方案数。

这样对于任意一条不合法的路径,我们在且仅在它经过的第一个黑色格子那里减掉了,不重不漏。

CF567F Mausoleum

发现从 \(n\to 1\) 每次在两侧放能保证先不降后不升,所以区间 DP。每次放两个相同的数,分全在左边/一左一右/全在右边三种情况,把合法的情况加起来即可。

CF590D Top Secret Task

容易发现交换次数这么大显然是无用的,最坏情况只是把后半部分的数移到前半部分而已,为 \(\lfloor\frac{n}{2}\rfloor\times\lfloor\frac{n+1}{2}\rfloor\)

所以完全可以记入状态。令 \(f_{i,j,p}\) 表示前 \(i\) 个数,选定了 \(j\) 个数,操作次数至多\(p\) 的最小和:

\[f_{i,j,p}=\min\{f_{i,j-1,p-(i-j)}+q_i\} \]

CF37D Lesson Timetable

一开始可能会想着从后往前搞,但你不能确定当前教室有多少组搞到后面去了,也就不能确定当前教室还能放多少组。

所以考虑从前往后搞,令 \(f_{i,j}\) 表示有 \(j\) 组第二次上课是在前 \(i\) 个教室的方案数:

\[f_{i,j}=\sum f_{i-1,j-k}\times\binom{\left(\sum_{o=1}^i x_o\right)-(j-k)}{k} \]

注意第一次上课的教室安排并没有确定小组编号,所以最后答案要乘上 \(\dfrac{(\sum x)!}{\prod x!}\)

posted @ 2023-12-18 15:38  御坂夏铃  阅读(7)  评论(0编辑  收藏  举报