2024-3月 DP 总结

换根 DP

  • 换根 DP,又称二次扫描,一般用于求解无根树问题。大多数时候将 \(n\) 次 dfs 简化为 \(2\) 次从而优化算法。

经典套路:

\(1.\) 指定某个节点为根节点(一般为 \(1\))。

\(2.\) 第一次搜索完成预处理,同时得到该节点的解。

\(3.\) 第二次搜索进行换根 DP,由已知节点推出相邻节点。

具体地,设 \(f\)\(g\) 两个数组分别表示第一次子树内的答案和以其为根的答案(也可以设子树外的答案)。第一次 dfs 处理 \(f\),第二次 dfs 通过父亲的 \(g\) 推出儿子。也即第一次自底向上,第二次自顶向下。这就是所谓“换根”的过程。

例题1 P3478 [POI2008] STA-Station

【题意】

给出一棵树,找出一个点来,使得以这个点为根时所有点的深度之和最大。

【解析】

\(f_i\) 表示 \(i\) 子树内的答案,则显然地,\(f_u=\sum_{v\in u}f_v+siz_v\),这里的 \(siz\) 表示子树大小。

第二次 dfs,考虑设 \(g_i\) 表示以 \(i\) 为整棵树的根的答案。则 \(g_v=g_u+n-2\times siz_v\)。特殊地,\(g_1=f_1\)

答案为 \(\max g_i\),时空复杂度 \(O(n)\)

例题2 CF1156D 0-1-Tree

可以左转我的题解。



斜率优化 DP

  • 斜率优化,一般是在转移方程中当前为 \(i\),枚举决策点 \(j\),然后化简式子出现同时与 \(i\)\(j\) 有关的项(如果没有可以单调队列)。这样的话有点像一次函数,形如 \(y=kx+b\),那么这里的 \(kx\) 就是与\(i\)\(j\) 有关的项(具体题目具体分析)。问题变成查询最有决策点。

  • 如果式子中的 \(x\)\(y\) 都有单调性,可以使用单调队列线性维护。否则有两种做法:维护凸壳并二分或李超树(也可以平衡树或 cdq 分治,但我不会,就不弄巧成拙了)。这些做法是带一个 log 的。

经典套路:

\(1.\) 写出朴素转移方程。

\(2.\) 化简并设出 \(x,y,k,b\),根据所求决定维护上凸还是下凸(最大值还是最小值)。

\(3.\) 看单调性决定维护方式。

例题1 P3195 [HNOI2008] 玩具装箱

【题意】

给定一个序列,要求将其划分成若干段,一段划分为 \([i,j]\) 的费用为 \((j-i+\sum_{k=i}^jC_k-L)^2\)(这里的 \(C_k\) 为给定数组,\(L\) 为给定常量)。最小化划分序列的费用和。

【解析】

朴素的转移方程为:(设 \(f_i\) 表示考虑到 \(i\) 的答案,\(s_i\) 表示 \(C_i\) 的前缀和)

\[f_i=\min_{1\le j<i}(f_j+[i-(j+1)+s_i-s_j-L]^2) \]

换元并化简,设 \(a_i=s_i+i,b_i=s_i+i+L+1\)

\[\begin{aligned} &f_i=\min_{1\le j<i}(f_j+[a_i-b_j]^2)\\ &f_i=\min_{1\le j<i}(f_j+a_i^2+b_j^2-2\times a_i\times b_j)\\ \end{aligned} \]

先不管取 \(\min\),先推式子,并把只与 \(j\) 有关的移到一边,尝试分离 \(i\)\(j\)

\[\begin{aligned} f_i&=f_j+a_i^2+b_j^2-2\times a_i\times b_j\\ f_j+b_j^2&=f_i-a_i^2+2\times a_i\times b_j \end{aligned} \]

我们发现,如果设 \(y=f_j+b_j^2,k=2\times a_i,x=b_j,b=f_i-a_i^2\),那么方程变成了一个一次函数形式 \(y=kx+b\)。所以要做的就是在二维平面中找一个斜率固定的直线使 \(b\) 最小。

观察数据,\(y=f_j+b_j^2\)\(x=b_j\) 都单调递增,所以使用单调队列优化,时空复杂度线性。

posted @ 2024-03-25 10:36  Mr_KaYa  阅读(19)  评论(0)    收藏  举报