Loading

【学习笔记】DP 优化 3:闵可夫斯基和优化 DP

Page Views Count

概述

用于优化 \((\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)\)

参考资料

posted @ 2023-09-01 20:02  SoyTony  阅读(594)  评论(2编辑  收藏  举报