2023.8.30 dp 经典题

由于笔者 Dp 水平过于低,故总结一些题目。

P2224 [HNOI2001] 产品加工

首先考虑暴力 dp,\(f_{i,j,k}\) 表示做到第 \(i\) 个任务时,A 做了 \(j\) 时间,B 做了 \(k\) 时间。
可以由 \(f_{i-1,j-t1,k},f_{i-1,j,k-t2},f_{i-1,j-t3,k-t3}\) 转移而来。

然而这实在是太劣了。
考虑缩减一维,设 \(f_{i,j}\) 表示做到第 \(i\) 个任务时,A 做了 \(j\) 时间,B 最少做多少时间。
可以由 \(f_{i-1,j-t1},f_{i-1,j}+t_2,f_{i-1,j-t3}+t_3\) 转移。

P7967 [COCI2021-2022#2] Magneti

考虑先把 \(r_i\) 排序一下。
我们这样设计状态:\(f_{i,j,k}\) 表示当前放了前 \(i\) 个磁铁,已经分成了 \(j\) 组,每组的半径和为 \(k\).
假设所有磁铁都是紧密相连的。(即不能再缩小半径了)
新开一个组:\(f_{i,j,k}\leftarrow f_{i,j-1,k-1}\).
放在一组的左边或右边:\(f_{i,j,k}\leftarrow 2 f_{i-1,j,k-r_i}\)
合并两个组:\(f_{i,j,k}\leftarrow C(n,2) \times f_{i-1,j+1,k-2r_i}\)
初始时:\(f_{1,1,0}=1\).
答案:\(\sum f_{n,1,k}\times C(l,k)\).

P6442 [COCI2011-2012#6] KOŠARE

将箱子的元素看成二进制数,再全部取反,将问题转化为与起来为 \(0\) 的方案数。
首先求出 \(cnt_i\) 表示含以 \(i\) 为子集的箱子有多少个。
然后做一个高维前缀和,求出 \(cnt_i\) 表示 \(i\) 的子集有多少个。
再求 \(g_i=2^{cnt_i}-1\) 表示方案数。
最后枚举 \(i\),若 \(i\) 包含偶数位元素,那么 \(g_i\) 贡献为正,否则为负。

P7962 [NOIP2021] 方差

发现操作就是交换差分。那么就是求任意排列差分数组后最小的方差。
发现差分的排列应该是一个谷的形式。
那么我们考虑将差分数组从小到大排序,我们加入一个数,只需考虑其是在左边还是右边。
再看 \(s^2=n\sum a_i^2-(\sum a_i)^2\)
直接处理很难,我们考虑将其拆分成两个值:和、平方和。
那么我们这样设计状态:\(f_{i,j}\) 表示当前加入了 \(i\) 个,和为 \(j\) 的最小平方和。
转移是轻松的。

posted @ 2023-08-30 14:35  s1monG  阅读(23)  评论(0编辑  收藏  举报