斜率优化小结
2015-12-31 09:25
176 查看
看网上的斜率优化都比较玄。。。
gerw给出了一种比较好的理解方式
简单的有两种形式
一、形如 dp(i) = min / max {f(j) + g(i) * h(j) + c(i)} (j < i) //h() 一般是有单调性的
显然c(i)是可以拿出来的,就变成了
dp(i) = min / max {f(j) + g(i) * h(j)} + c(i)
g(i)对于一个i来说是定值,不妨设为k
将优化目标设为z = f(j) + k * h(j)
每个j在二维平面上对应一个点(h(j), f(j))
则z = y + kx
即y = -kx + z
则问题转化为给出平面上一些点,求斜率为-k且至少经过这些点中的一个的直线中y轴截距最大/最小的点,显然分情况维护上凸壳或者下凸壳,由于h()单调,维护一个栈就行了,要是无序,拿平衡树就行了
另外如果g(i)单调只用维护一个单调队列,O(n)即可,否则需要二分或三分。
二、给定一个点与之前的一些点,求过这个点和之前某个点的所有直线中,斜率最大/最小的直线
情况差不多,根据单调性维护上凸壳或者下凸壳
gerw给出了一种比较好的理解方式
简单的有两种形式
一、形如 dp(i) = min / max {f(j) + g(i) * h(j) + c(i)} (j < i) //h() 一般是有单调性的
显然c(i)是可以拿出来的,就变成了
dp(i) = min / max {f(j) + g(i) * h(j)} + c(i)
g(i)对于一个i来说是定值,不妨设为k
将优化目标设为z = f(j) + k * h(j)
每个j在二维平面上对应一个点(h(j), f(j))
则z = y + kx
即y = -kx + z
则问题转化为给出平面上一些点,求斜率为-k且至少经过这些点中的一个的直线中y轴截距最大/最小的点,显然分情况维护上凸壳或者下凸壳,由于h()单调,维护一个栈就行了,要是无序,拿平衡树就行了
另外如果g(i)单调只用维护一个单调队列,O(n)即可,否则需要二分或三分。
二、给定一个点与之前的一些点,求过这个点和之前某个点的所有直线中,斜率最大/最小的直线
情况差不多,根据单调性维护上凸壳或者下凸壳
相关文章推荐
- 为ListView每个Item上面的按钮添加事件在Adapter中响应
- 我们一起学python-helloworld
- C++ 工具类 [StrUtil] 和 工具方法
- 在启动Windows Process Activation Service时,出现错误13:数据无效
- linux常用命令(二)
- Python标准库11 多进程探索 (multiprocessing包)
- LeetCode-29-Divide Two Integers(Numbers)-Medium
- 架构师于小波:魅族实时消息推送架构
- 如何在小部件列表中隐藏某个widget或者shortcut
- Xcode中因为证书报错的常见问题
- iOS开发之远程推送Push
- opencv图像数据操作
- Team Leader 你不再只是编码, 来炖一锅石头汤吧
- Linux 动态链接库的编译和使用实例
- 时间转换代码
- ORA-16447 Redo apply was not active at the target standby database
- 常用shell命令实战
- linux系统分区与挂载
- 在Activity中响应ListView内部按钮的点击事件的两种方法
- ZOJ1232 Adventure of Super Mario(DP+SPFA)