前言

考试 T2 出题人放了个树上斜率优化 DP,直接被同校 OIER 吊起来锤。

离 NOIP 还有不到一周,赶紧学一点。

引入

斜率

斜率,数学、几何学名词,是表示一条直线(或曲线的切线)关于(横)坐标轴倾斜程度的量。它通常用直线(或曲线的切线)与(横)坐标轴夹角的正切,或两点的纵坐标之差与横坐标之差的比来表示。

斜率可以用来描述一个坡的倾斜程度,公式 \(k = \frac{\Delta y}{\Delta x}\)。

初中学过一元一次函数 \(y = kx + b\),这里的 \(k\) 就是这个函数表示的直线的斜率。

解决什么

一般对于形如 \(f[i] = \min(a[i] \times b[j] + c[i] + d[j])\) 这种类型的 DP 转移式子都可以用上斜率优化。

其中 \(b\) 要满足单调递增。

看到中间有一部分与 \(i,j\) 都有关,所以这个时候要用到斜率优化。

理解

下面来以一道题目为例进行讲解。

P3195 [HNOI2008] 玩具装箱

看完题目应该都可以想出来一个 \(O(n^2)\) 的 DP,那就是:

设 \(f[i]\) 表示考虑到第 \(i\) 个玩具所用的最小花费,\(sum[i]\) 为从 \(1\sim i\) 的玩具长度总和。

\[f[i] = \min\{f[j] + (sum[i] - sum[j] + i - j - L - 1)^2\}
\]

我们尝试把这一堆东西分分类,把只有 \(i\) 的挪到一起,只有 \(j\) 的挪到一起,剩下的挪到中间。

得到:

\[f[i] = \min\{f[j] + (sum[i] + i - sum[j] - j - L - 1)^2\}
\]

设 \(A=sum[i] + i, B = sum[j] - j - L - 1\)。

那么就是 :

\[f[i] = f[j] + A^2 -2AB + B^2
\]

显然的,\(A^2\) 我们可以预处理,是已知的,由于前缀和,而且玩具长度至少为 \(1\),所以 \(2A\) 是严格单调递增的,\(B\) 数组我们也可以直接预处理。

\[f[j] + B^2 = 2AB + f[j] + A^2
\]

这个式子是把只与 \(j\) 有关的移到左边了,可以发现形式上是和 \(y = kx + b\) 一样的。

那么我们就可以把一个之前转移完成的状态看成是一个 \((B, f[j] + B^2)\) 的点,而 \(2A\) 就是经过他们的直线的斜率。

那么我们要求 \(f[i]\) 的话,就是求这个点和这个斜率为 \(2A\) 的直线的最大可能截距是多少。

于图像中

假设下面的三个点是我们待选的状态:

假设我们当前要求的斜率画出来是下面这样:

我们就从下往上,一点一点向上挪,直到碰到的第一个点,此时的截距一定最大。我们也能看出的确 \(C\) 点最优。

那么此时的 \(A\) 点好像没有什么用了,可以扔掉吗?

答案是可以,因为斜率是单调递增的,既然这次第一个碰不到 \(A\),那么后面肯定也不是第一个碰到。

但是我们如何做到最快找出呢?

队列维护

观察这张图片,假设里面的点都是之前转移完的状态。

比较 \(AE,AB\) 的斜率。

不难发现 \(AB\) 的斜率比 \(AE\) 小,想一下之前说的,如果拿一条直线去碰这个图形,从各个角度去碰,最外层的点会形成一个凸包,而这个凸包内的点,是无论如何都碰不到的。

这个我们可以用一个队列来维护一个下凸壳,也就是凸包的一部分。

然后根据上面说的,要是队列头的两个元素形成的直线斜率比当前的小,也可以直接弹出。

这样队列的队头元素就是我们要转移的值了。

code:


/*
* @Author: Aisaka_Taiga
* @Date: 2023-11-13 14:11:27
* @LastEditTime: 2023-11-13 15:09:40
* @LastEditors: Aisaka_Taiga
* @FilePath: \Desktop\P3195.cpp
* The heart is higher than the sky, and life is thinner than paper.
*/
#include <bits/stdc++.h> #define pf(x) ((x) * (x))
#define int long long
#define DB double
#define N 1000100 using namespace std; inline int read()
{
int x = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();}
while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return x * f;
} int n, L, q[N], c[N], f[N], sum[N], A[N], B[N]; inline int X(int x){return B[x];} inline int Y(int x){return f[x] + pf(B[x]);} inline DB xl(int i, int j){return (Y(i) - Y(j)) * 1.0 / (X(i) - X(j));} signed main()
{
n = read(), L = read();
for(int i = 1; i <= n; i ++) c[i] = read();
for(int i = 1; i <= n; i ++)
{
sum[i] = sum[i - 1] + c[i];
B[i] = sum[i] + i + L + 1;
A[i] = sum[i] + i;
}
B[0] = L + 1;
int h = 1, t = 1;
for(int i = 1; i <= n; i ++)
{
while(h < t && xl(q[h], q[h + 1]) < 2 * A[i]) h ++;
int j = q[h];
f[i] = f[j] + pf(A[i] - B[j]);
while(h < t && xl(q[t - 1], i) < xl(q[t - 1], q[t])) t --;
q[++ t] = i;
}
cout << f[n] << endl;
return 0;
}

参考:https://www.cnblogs.com/terribleterrible/p/9669614.html

浅谈斜率优化DP的更多相关文章

  1. 斜率优化dp(POJ1180 Uva1451)

    学这个斜率优化dp却找到这个真心容易出错的题目,其中要从n倒过来到1的确实没有想到,另外斜率优化dp的算法一开始看网上各种大牛博客自以为懂了,最后才发现是错了. 不过觉得看那些博客中都是用文字来描述, ...

  2. UVALive 4726 Average ——(斜率优化DP)

    这是第一次写斜率优化DP= =.具体的做法参照周源论文<浅谈数形结合思想在信息学竞赛中的应用>.这里仅提供一下AC的代码. 有两点值得注意:1.我这个队列的front和back都是闭区间的 ...

  3. 浅谈状态压缩DP

    浅谈状态压缩DP 本篇随笔简单讲解一下信息学奥林匹克竞赛中的状态压缩动态规划相关知识点.在算法竞赛中,状压\(DP\)是非常常见的动规类型.不仅如此,不仅是状压\(DP\),状压还是很多其他题目的处理 ...

  4. bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)

    题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...

  5. bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)

    题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...

  6. [BZOJ3156]防御准备(斜率优化DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP

  7. 【BZOJ-1096】仓库建设 斜率优化DP

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3719  Solved: 1633[Submit][Stat ...

  8. BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP

    1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...

  9. BZOJ 3156: 防御准备 斜率优化DP

    3156: 防御准备 Description   Input 第一行为一个整数N表示战线的总长度. 第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai. Output 共一个整数,表示最小的战 ...

  10. HDU2829 Lawrence(斜率优化dp)

    学了模板题之后上网搜下斜率优化dp的题目,然后就看到这道题,知道是斜率dp之后有思路就可以自己做不出来,要是不事先知道的话那就说不定了. 题意:给你n个数,一开始n个数相邻的数之间是被东西连着的,对于 ...

随机推荐

  1. KVM VM 添加 usb 设备

    制作xml文件 参考链接:https://libvirt.org/formatdomain.html#usb-pci-scsi-devices <hostdev mode='subsystem' ...

  2. SpringBoot3数据库集成

    标签:Jdbc.Druid.Mybatis.Plus: 一.简介 项目工程中,集成数据库实现对数据的增晒改查管理,是最基础的能力,而对于这个功能的实现,其组件选型也非常丰富: 通过如下几个组件来实现数 ...

  3. Nessus 10.5.3 漏洞扫描器的下载安装与卸载

    测试环境 Kali 2023.2 本教程使用脚本进行自动化安装.破解 文章地址:https://www.iculture.cc/software/pig=25546#wznav_7 偶然发现,特别好用 ...

  4. 【HCDG城市行东莞站】松山湖开发者村助力企业释放数字新动能

    本文分享自华为云社区<[HCDG城市行东莞站]从"数据治理"洞察"数字化运营之道",松山湖开发者村助力企业释放数字新动能!>,作者:华为云社区精选. ...

  5. TypeScript中Class基础使用

    TypeScript是一种静态类型的JavaScript超集,它提供了许多增强的功能,其中之一就是对面向对象编程的支持.在TypeScript中,我们可以使用Class来定义类,这使得我们能够更加结构 ...

  6. PGO in Go 1.21

    原文在这里. 由 Michael Pratt 发布于 2023年9月5日 在2023年早些时候,Go 1.20发布了供用户测试的概要版本的基于性能分析的优化(PGO).经过解决预览版已知的限制,并得益 ...

  7. KRPANO资源分析工具下载720THINK全景图

    提示:目前分析工具中的全景图下载功能将被极速全景图下载大师替代,相比分析工具,极速全景图下载大师支持更多的网站(包括各类KRPano全景网站,和百度街景) 详细可以查看如下的链接: 极速全景图下载大师 ...

  8. Oracle为表添加约束

    转载自:https://blog.csdn.net/qq_38662525/article/details/94192475 创建一个学生表和院系表:院系表为主表,学生表为从表   create ta ...

  9. SQL Server更改表字段顺序和表结构

    1.首先打开SqlServer,SSMS可视化工具.点击工具,再点选项. 2.在弹出的选项窗口中,点击Desinners,点击表设计和数据库设计器,将阻止保护勾去掉.点"确定" 3 ...

  10. 【解惑】时间规划,Linq的Aggregate函数在计算会议重叠时间中的应用

    在繁忙的周五,小悦坐在会议室里,面前摆满了各种文件和会议安排表.她今天的工作任务是为公司安排下周的50个小会议,这让她感到有些头疼.但是,她深吸了一口气,决定耐心地一个一个去处理. 首先,小悦仔细地收 ...