(原来的题解没得了,只好重写一份)

斜率优化一般是,\(dp\) 是枚举一个 \(i\),然后前面找一个 \(j\),式子中有些和 \(j\) 有关,有些和 \(i\) 有关,有些和俩都有关。

过程中,我们维护一个单调队列,它们可能作为最优的转移位置。其中队首是最优的,其它的是 可能 成为最优的(现在不是,可能以后)

核心步骤:把每个决策转化成平面直角坐标系上的点,然后从几何的角度考虑哪些点可能是最优的,哪些不可能。

我们发现这个性质好像很妙。所以说,不是所有题都可以斜率优化的。

这些说的肯定非常迷惑,看个实际的

示例

最经典的入门题 HNOI2008玩具装箱

转移方程为 \(f_i=min(f_j+(s_i-s_j+i-j-L-1)^2)\),非常 simple

我们令和 \(i\) 有关的为 \(a_i=s_i+i\),和 \(j\) 有关的为 \(b_j=s_j+j+L+1\)

那 \(f_i=min(f_j+(a_i-b_j)^2)\)

拆开 \(f_i=min(f_j+a_i^2-2a_ib_j+b_j^2)\)

假设 \(j\) 是最优的那个转移,那

\(f_i=f_j+a_i^2-2a_ib_j+b_j^2\)

这个式子里面,注意到 \(2a_ib_j\) 这一项是同时与俩有关的。

主体思想

我们把和 \(i\) 有关的那个 \(2a_i\) 看成斜率,和 \(j\) 有关的 \(b_j\) 看成 \(x\)。那 \(y\) 肯定也要和 \(j\) 有关,移到右边。我们的主体思想是把 \(f_i\) 变成一个截距。所以把 \(f_i\) 和一些只和 \(i\) 有关的东西放到左边。

(这一步就体现出“斜率”了)

变成 \(2a_ib_j+f_i-a_i^2=b_j^2+f_j\)。其中 \(x=b_j\),\(y=b_j^2+f_j\)。

令 \(P_j\) 作为第 \(j\) 个决策点,坐标为 \((b_j,b_j^2+f_j)\)。

那现在问题转化成了:找到一个 \(j<i\),使得过点 \(P_j\) 的斜率为 \(2a_i\)(定值)的直线的截距加上 \(a_i^2\)(定值)最小。

手画几张图可以得出以下结论:

  • 如果队首的斜率 \(<2a_i\),那这一次转移队首就比队首的下一个要劣(画图发现);而且 \(a_i\) 是单增的,那以后肯定都劣,直接弹队首
  • 斜率应该是单调递增的 (这个要手画了)。所以如果新来的和原队尾组成的斜率,小于原队尾和原队尾上一个的斜率,那这个队尾就废了

然后就维护一个单调队列就完事了。复杂度是 \(O(n)\) 的,\(log\) 都不带。

代码

最新文章

  1. jsp编程
  2. P1038 神经网络
  3. linux C(hello world)最大公约数和最小公倍数
  4. 程序里面的system.out.println()输出到其他位置,不输出到tomcat控制台。
  5. 伪元素”:after” , “:before&quot;
  6. NYOJ_23_取石子(一)
  7. Java最大公约数和最小公倍数的求法(辗转相除法)
  8. 更新下载库update绝对详解
  9. 其它综合-使用Putty远程连接管理Linux实践
  10. #195 game(动态规划+二分)
  11. Python语音识别(计算器)
  12. 更好用的excel国际化多语言导出
  13. png转tif
  14. 学习Java的第一天
  15. 异步任务利器Celery(二)在django项目中使用Celery
  16. keepalived之单播----k8sHA准备
  17. java 轨迹栈
  18. Tomcat 自动化部署
  19. 在 C++ 程序中只使用 const 常量而不使用宏常量
  20. C++11新特性之0——移动语义、移动构造函数和右值引用

热门文章

  1. select * from 多张表的用法
  2. 【转】PANDAS 数据合并与重塑(concat篇)
  3. ssrf与gopher与redis
  4. Liunx运维(七)-用户管理及用户信息查询命令
  5. 搭建web攻防环境
  6. 如何将未呈现的WPF控件保存到图片
  7. vim 手动添加脚本头部信息
  8. Openstack neutron 网络服务 (七)
  9. Session、Cookie与Token
  10. 【Oracle】11G 11.2.0.4 RAC环境打补丁