【学习笔记】四边形不等式优化 DP
决策单调性
- 对于最优化问题
,称 为成本函数,参数为 的最优化问题称为问题 ,记问题 对应的最小最优决策点为 。其中,我们假设成本函数 可以 计算。 - 决策单调性指对于任意
均有 。 - 最常见的判断决策单调性的方法是通过四边形不等式。
四边形不等式
- 在成本函数
中,若对于任意 均有 则称函数 满足四边形不等式,简记为“交叉小于包含”。若等号恒成立,又称函数 满足四边形恒等式。 - 定理
- 在满足四边形不等式的函数
中,对于任意 均有 。- 证明:用
代入定义中的 即可。
- 证明:用
- 若函数
满足四边形不等式,则最优化问题 满足决策单调性。- 证明
- 对于任意
,由最优性均有 。 - 对于任意
,由四边形不等式均有 ,移项得到 。 - 将两个不等式相加,得到
,进而得到 ,即最优化问题 满足决策单调性。
- 对于任意
- 证明
- 在满足四边形不等式的函数
- 四边形不等式优化利用的是状态转移方程中的决策单调性。
一维线性 DP 的四边形不等式优化
基础知识
- 对于形如
的状态转移方程,若成本函数 满足四边形不等式,则 满足决策单调性。- 证明
- 类比
的证明方式,将 代入可得到 满足四边形不等式,进而推出 满足决策单调性。
- 类比
- 证明
- 常见的实现方式是分治和二分队列,二者各有优缺点,视情况决定使用哪种实现方法,时间复杂度均为
。- 分治
- 求解所有状态只需要知道所有决策点。考虑分治过程中先求出中点处
的决策点,更新区间范围内决策点的上下界。
- 求解所有状态只需要知道所有决策点。考虑分治过程中先求出中点处
- 二分队列
- 考虑维护
,在枚举至 时,先前的 一定形如 。在插入 时要保证满足决策单调性和最优性,这就需要我们找到一个位置 使得 目前存储的决策都比 好,而 目前存储的决策都比 差,接着将 全部修改为 。 - 因为
中存在许多相同的元素,且暴力修改效率较低,可将相同元素试做一个块 表示 。 - 同时,由于决策单调性的存在,我们没有必要保存
的部分来减少不必要的决策,单调队列就可以维护了。 - 算法流程
插入 。- 如果存在
这个决策的话。
- 如果存在
- 对于任意
,顺序执行以下操作。 取出队头并检查队头是否过时,即 是否 。若已过时则删除队头,否则令 。 令队头作为最优决策进行状态转移。 取出队尾,进行分讨。若对于 来看 比 更优,则令 ,删除队尾并本步骤重新开始;若对于 来看 比 更差,则插入新决策 ;否则,在 上进行二分查找 使得在此之前 更优,在此之后 更优,插入新决策 。
- 考虑维护
例题
- 分治
luogu P3515 [POI2011] Lightning Conductor
-
多倍经验: luogu P5503 [JSOI2016] 灯塔 | SP9070 LIGHTIN - Lightning Conductor
-
设
表示使 成立的最小非负整数,移项状态转移方程为 。 -
当
时,原式为 。- 令
,有 满足四边形不等式。- 证明
- 将式子拆开后等价于证明
移项有 ,令 ,等价于证明 ,左右平方后有 。原结论成立。
- 将式子拆开后等价于证明
- 证明
- 令
-
当
时,有 。 -
当
时,将 翻转即可。点击查看代码
ll a[500010],f[500010]; deque<ll>qj,ql,qr; double w(ll x,ll y) { return a[x]+sqrt(y-x); } void solve(ll n) { qj.clear(); ql.clear(); qr.clear(); for(ll i=1;i<=n;i++) { while(qj.empty()==0&&qr.front()<i) { qj.pop_front(); ql.pop_front(); qr.pop_front(); } if(qj.empty()==0) { ql.front()=i; f[i]=max(f[i],-a[i]+((ll)(ceil(a[qj.front()]+sqrt(i-qj.front()))))); } while(qj.empty()==0&&w(qj.back(),ql.back())<=w(i,ql.back())) { qj.pop_back(); ql.pop_back(); qr.pop_back(); } if(qj.empty()==0) { if(w(qj.back(),n)<w(i,n))//保证有优于 i 的决策 { ll l=ql.back(),r=n,mid; while(l<=r) { mid=(l+r)/2; if(w(qj.back(),mid)<w(i,mid)) { r=mid-1; } else { l=mid+1; } } qr.back()=r; qj.push_back(i); ql.push_back(l); qr.push_back(n); } } else { qj.push_back(i); ql.push_back(i); qr.push_back(n); } } } int main() { ll n,i; cin>>n; for(i=1;i<=n;i++) { cin>>a[i]; } solve(n); reverse(a+1,a+1+n); reverse(f+1,f+1+n); solve(n); reverse(f+1,f+1+n); for(i=1;i<=n;i++) { cout<<f[i]<<endl; } return 0; }
luogu P1912 [NOI2009] 诗人小G
-
令
表示前 句诗加空格的长度,即 。 -
设
表示将前 句诗排版后的最下协调度,状态转移方程为 。 -
拆掉绝对值后求导即可证明
是满足决策单调性的。- 还没学导数,具体证明先咕了。
-
中途会炸
__int128_t
需要使用long double
代替;手写快速幂来减小时间复杂度。点击查看代码
ll sum[100010],ans[100010]; long double f[100010]; char s[100010][40]; deque<ll>qj,ql,qr; long double qpow(long double a,ll b) { long double ans=1; while(b) { if(b&1) { ans=ans*a; } b>>=1; a=a*a; } return ans; } long double w(ll j,ll i,ll L,ll p) { return f[j]+qpow(abs(sum[i]-sum[j]-L-1),p); } void print(ll x) { if(x==0) { return; } else { print(ans[x]); for(ll i=ans[x]+1;i<=x;i++) { cout<<(s[i]+1); if(i!=x) { cout<<" "; } } cout<<endl; } } int main() { ll t,n,L,p,l,r,mid,i,j; cin>>t; for(j=1;j<=t;j++) { cin>>n>>L>>p; memset(ans,0,sizeof(ans)); for(i=1;i<=n;i++) { cin>>(s[i]+1); sum[i]=sum[i-1]+strlen(s[i]+1)+1; } qj.clear(); ql.clear(); qr.clear(); qj.push_back(0); ql.push_back(1); qr.push_back(n); for(i=1;i<=n;i++) { while(qj.empty()==0&&qr.front()<i) { qj.pop_front(); ql.pop_front(); qr.pop_front(); } if(qj.empty()==0) { ql.front()=i; f[i]=w(qj.front(),i,L,p); ans[i]=qj.front(); } while(qj.empty()==0&&w(qj.back(),ql.back(),L,p)>=w(i,ql.back(),L,p)) { qj.pop_back(); ql.pop_back(); qr.pop_back(); } if(qj.empty()==0) { if(w(qj.back(),n,L,p)>w(i,n,L,p)) { l=ql.back(); r=n; while(l<=r) { mid=(l+r)/2; if(w(qj.back(),mid,L,p)>w(i,mid,L,p)) { r=mid-1; } else { l=mid+1; } } qr.back()=r; qj.push_back(i); ql.push_back(l); qr.push_back(n); } } else { qj.push_back(i); ql.push_back(i); qr.push_back(n); } } if(f[n]>1e18) { cout<<"Too hard to arrange"<<endl; } else { cout<<(ll)f[n]<<endl; print(n); } cout<<"--------------------"<<endl; } return 0; }
LibreOJ 6039. 「雅礼集训 2017 Day5」珠宝 /「NAIPC2016」Jewel Thief
二维区间 DP 的四边形不等式优化
基础知识
- 若对于任意的
均有 ,则称 对于区间包含关系具有单调性。 - 对于形如
的状态转移方程,其中 ,若 满足四边形不等式和区间包含单调性,那么 也满足四边形不等式。- 证明
- 考虑数学归纳法。
- 当
时,有 满足四边形不等式。- 由
,有 。 - 若
的最优决策是 ,则 。 - 若
的最优决策是 ,则 。 - 故
时,有 满足四边形不等式。
- 由
- 假设当
时,有 满足四边形不等式。 - 当
时,设 是 的最优决策, 是 的最优决策,不妨设 。有 。又因为 ,有 。故当 时,有 满足四边形不等式。 - 故
满足四边形不等式。
- 证明
- 定理
- 对于形如
的状态转移方程,其中 ,若 满足四边形不等式,那么对于任意 均有 ,即满足二维决策单调性。- 证明
- 由于
满足四边形不等式,对于任意的 均有 ,移项得到 。 - 又因为
,移项有 。 - 对于
有 ,说明 一定不比 更优,故 。 同理。
- 由于
- 证明
- 对于形如
例题
luogu P1775 石子合并(弱化版)
-
令
。显然有 满足四边形恒等式。 -
设
表示把最初的第 堆合并成一堆需要消耗的最少体力,状态转移方程为 ,边界为 。 -
由于
满足四边形不等式,故仅枚举 ,时间复杂度为 。点击查看代码
ll a[2010],sum[2010],f[2010][2010],opt[2010][2010]; ll w(ll l,ll r) { return sum[r]-sum[l-1]; } int main() { ll n,i,len,l,r,k; cin>>n; memset(f,0x3f,sizeof(f)); for(i=1;i<=n;i++) { cin>>a[i]; sum[i]=sum[i-1]+a[i]; f[i][i]=0; opt[i][i]=i; } for(len=2;len<=n;len++) { for(l=1,r=l+len-1;r<=n;l++,r++) { for(k=opt[l][r-1];k<=opt[l+1][r];k++) { if(f[l][k]+f[k+1][r]+w(l,r)<f[l][r]) { f[l][r]=f[l][k]+f[k+1][r]+w(l,r); opt[l][r]=k; } } } } cout<<f[1][n]<<endl; return 0; }
满足四边形不等式的函数类
- 若函数
和 均满足四边形不等式(或区间包含单调性),则对于任意 均有 也满足四边形不等式(或区间包含单调性)。 - 若对于函数
存在函数 使得 ,则函数 满足四边形不等式。且当函数 单调递增时,函数 也满足区间包含单调性。 - 设
是一个单调递增的凸函数,若函数 满足四边形不等式和区间包含单调性,则复合函数 也满足四边形不等式和区间包含单调性。 - 设
是一个凸函数,若函数 满足四边形恒等式和区间包含单调性,则复合函数 也满足四边形不等式。
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18295297,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效