【学习笔记】DP 优化 3:闵可夫斯基和优化 DP
概述
用于优化 \((\max/\min,+)\) 卷积,形如:
\[f_i=\max_{j=0}^i/\min_{j=0}^i \{g_j+h_{i-j}\}
\]
要求 \(g,h\) 具有凸性。
算法流程
以 \(\max\) 为例,要求 \(g,h\) 形成上凸包,对 \(g,h\) 差分,那么 \(f_i\) 相当于在 \(\Delta g\) 和 \(\Delta h\) 中选两个前缀,要求长度和为 \(i\),权值和最大。由于 \(\Delta g\) 和 \(\Delta h\) 都单调不升,那么归并排序之后选前 \(i\) 个数就是最优。
同理 \(\min\) 要求 \(g,h\) 形成下凸包。
vector<int> Minkowski(vector<int> g,vector<int> h){
vector<int> f;
for(int i=(int)g.size()-1;i>=1;--i) g[i]-=g[i-1];
for(int i=(int)h.size()-1;i>=1;--i) h[i]-=h[i-1];
f.resize(g.size()+h.size());
merge(g.begin(),g.end(),h.begin(),h.end(),f.begin(),greater<int>());
for(int i=1;i<f.size();++i) f[i]+=f[i-1];
return f;
}
优化 DP
通常与分治同时使用。
转移方程形如:
\[f_{i,j}=\max_{j=0}^i/\min_{j=0}^i \{f_{i-1,j}+w_{i,i-j}\}
\]
若 \(f,w\) 均具有凸性,可以使用闵可夫斯基和优化至 \(O(n)\) 转移一行,改成分治求区间的 \(f\) 值,每一层的总规模 \(O(n)\),可以做到 \(O(n\log n)\)。
例题
QOJ-5421 Factories Once More
考虑树上背包,设 \(f_{u,i}\) 为 \(u\) 子树内选 \(i\) 个节点的最大答案,转移是:
\[f_{u,i}=\max_{j=0}^{siz_v} \{f_{u,i-j}+f_{v,j}+j(k-j)\times w(u,v)\}
\]
注意到贡献函数是上凸的,转移形如 \((\max,+)\) 卷积,因此得知 \(f_u\) 是上凸的,那么维护差分数组使用闵可夫斯基和优化。
需要启发式合并,维护单调不升的差分数组使用 Splay,而 \(j(k-j)\times w(u,v)\) 差分后是等差数列,维护一个加等差数列的标记即可。
时间复杂度 \(O(n\log n)\)。