斜率优化初探:以 [HNOI2008]玩具装箱 为例
记 \(f[i]\) 表示装好前 \(i\) 个的最小花费。容易写出转移:
\]
直接转移是 \(O(n ^ 2)\) 的,我们考虑斜率优化。
斜率优化的过程
(一)问题转化成了求最小截距。
我们把 \(min\) 的外壳去掉,并且提前把 \(L +1\) (式子更简洁) 可以得到:
\]
把括号打开,可以得到:
\]
移项后得到:
\]
此时,如果我们把这看做一个一次函数,那么
x = s[j]\\
b = (f[i] - s[i] ^ 2 + 2 \times s[i] \times L)\\
y = f[j] + (s[j] +L) ^ 2
\]
注意到固定 \(i\) 后,\(k\) 是固定的。而对于每个 \(j\), 我们都可求出对应的 \((x, y)\)。此时当 \(b\) 最小时,\(f[i]\) 也会最小。
(二)截距在哪里最小?(图像理解)
我们知道有用的 \(j\) 在二维平面上形成的点阵是个凸包。
我们惊讶的发现斜率竟然是固定的!我们可以平移这条直线至与凸包相切,显然这个切点 \(E\), 就对应着最小的截距。
怎么找这个点呢?发现 \(E\) 点以前的斜率都小于当前 \(k\), \(E\) 点之后的斜率都大于等于 \(k\), 因此可以二分这个位置。时间复杂度 \(O(nlogn)\)。
(三)决策单调性的优化(图像理解)
决策单调性的定义:
设 \(j_0[i]\) 表示 \(f[i]\) 转移的最优决策点,那么 决策单调性 可以描述为 \(\forall i \le i'\), \(j_0[i] \le j_0[i']\)。即随着 \(i\) 递增,所找到的 最优决策点 是递增态(非严格递增)。
发现 \(k = 2s[i]\), 而 \(s[i]\) 是前缀和,显然是递增的,那么我们的决策点也一定会越来越大(因为目标斜率递增)
详细证明参见参考博客。
用单调队列维护凸包的点集,分三步:
- 将斜率比目标斜率小的点弹出, 在队首位置找到最优决策点 \(j\)。
- 用最优决策点 \(j\) 更新 \(dp[i]\)。
- 把新的点加入队列中。
时间复杂度 \(O(n)\)。
#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
#define int ll
using namespace std;
using ll = long long;
const int N = 1e5 + 5;
int L, n, h = 1, t = 0;
int f[N], s[N], q[N];
int X(int j){
return s[j] +L;
}
int Y(int j){
return f[j] + (s[j] + L) * (s[j] + L);
}
long double slope(int i, int j){
return (long double)(Y(i) - Y(j)) / (long double)(X(i) - X(j));
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> L;
++L;
F(i, 1, n) cin >> s[i], s[i] += s[i - 1] + 1;
q[++t] = 0;
F(i, 1, n){
while(h < t && slope(q[h], q[h + 1]) < 2 * s[i]) ++ h;
int j = q[h];
f[i] = f[j] + (s[i] - s[j] - L) * (s[i] - s[j] - L);
while(h < t && slope(q[t - 1], q[t]) > slope(q[t - 1], i)) -- t;
q[++ t] = i;
}
cout << f[n] << '\n';
return 0;
}
反思:移项的依据
为了用 \(Function(i)\) 表示出 \(Function(j)\),我们把含 \(i\) 的东西移到等式左边,把含 \(j\) 的东西移到等式右边。以此整理出 "不变的 \(k\),待求解的 \(b\),确定的 \(x, y\)"。 记得 \(f[i]\) 一定要放在截距 \(b\) 里面!因为我们是对 截距 求解极值。
注意 \(k, x, y\) 都是确定的,只有 \(b\) 是待定的。
参考博客:
【学习笔记】动态规划—斜率优化DP(超详细) - 辰星凌 - 博客园 (cnblogs.com)
斜率优化初探:以 [HNOI2008]玩具装箱 为例的更多相关文章
- 【斜率优化】BZOJ1010 [HNOI2008]玩具装箱toy
[题目大意] P教授有编号为1...N的N件玩具,第i件玩具长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的.如果将第i件玩具到第j个玩具放到一 个容器中,那么容器的长度将为 x ...
- BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 9812 Solved: 3978[Submit][St ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
- 【BZOJ 1010】 [HNOI2008]玩具装箱toy (斜率优化)
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 9330 Solved: 3739 Descriptio ...
- bzoj 1010 [HNOI2008]玩具装箱toy(DP的斜率优化)
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 7874 Solved: 3047[Submit][St ...
- bzoj1010[HNOI2008]玩具装箱toy 斜率优化dp
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 11893 Solved: 5061[Submit][S ...
- [HNOI2008]玩具装箱TOY --- DP + 斜率优化 / 决策单调性
[HNOI2008]玩具装箱TOY 题目描述: P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京. 他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器 ...
- BZOJ 1010: [HNOI2008]玩具装箱toy(DP+斜率优化)
[HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊 ...
- bzoj1010: [HNOI2008]玩具装箱toy(DP+斜率优化)
1010: [HNOI2008]玩具装箱toy 题目:传送门 题解: 很明显的一题动态规划... f[i]表示1~i的最小花费 那么方程也是显而易见的:f[i]=min(f[j]+(sum[i]-su ...
- Bzoj 1010: [HNOI2008]玩具装箱toy(斜率优化)
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MB Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定 ...
随机推荐
- MFC添加图标到托盘
MFC窗口实现最小化到托盘 右键菜单和还原 //.h文件 void toTray();//最小化到托盘 void DeleteTray();//删除托盘图标 afx_msg LRESULT OnSho ...
- 速通c++
文章目录 1.什么是c++. 2什么是面向对象,什么又是面向过程. 3.C++的灵魂,c++的类. 4.如何定义一个类. 5.什么是对象. 6.如何定义一个对象. 直接定义: 在堆里面定义. 删除对象 ...
- 【YashanDB数据库】由于网络带宽不足导致的jdbc向yashandb插入数据慢
问题现象 某客户环境,客户的业务使用jdbc驱动向其他操作系统上的yashandb插入90万条数据,耗时大约30分钟. 问题的风险及影响 影响客户的业务处理效率 问题影响的版本 所有的yashandb ...
- 【YashanDB数据库】VMware虚拟机使用默认安装,在掉电之后数据库无法启动
问题现象 客户使用VMware虚拟机使用默认安装,部署YashanDB个人版,在掉电之后无法启动 操作系统: Virtualization: VMware Operating System: Cent ...
- 【YashanDB知识库】IMP跨网络导入慢问题
问题现象 问题单:imp性能慢-通过异机导入性能下降太多-镜像环境可重现 现象: 同样一份数据290M, 在同一个机器本地导入,耗时2分钟多,本机用ip连接导入耗时4分钟多, 跨机器导入,耗时17分钟 ...
- SimCLR: 一种视觉表征对比学习的简单框架《A Simple Framework for Contrastive Learning of Visual Representations》(对比学习、数据增强算子组合,二次增强、投影头、实验细节很nice),好文章,值得反复看
现在是2024年5月18日,好久没好好地看论文了,最近在学在写代码+各种乱七八糟的事情,感觉要和学术前沿脱轨了(虽然本身也没在轨道上,太菜了),今天把师兄推荐的一个框架的论文看看(视觉CV领域的). ...
- c# 常用反射和表达式树整理
更新: 2021-06-19 反射 local function https://stackoverflow.com/questions/43348128/reflection-how-do-i-fi ...
- Figma 学习笔记 – Text
结构 Figma 的字都会有一个 wrapper 控制 width. 虽然它是看不见的. 但是你要知道它有那个概念存在. 按 T 键, 然后鼠标点击或拉就可以做出一个 text 了. 基本配置 我顺着 ...
- Flutter 2.5 更新详解
Flutter 2.5 正式版已于上周正式发布!这是一次重要的版本更新,也是 Flutter 发布历史上各项统计数据排名第二的版本.我们关闭了 4600 个 Issue,合并了 3932 个 PR,它 ...
- 林史·CLOI纪事本末
CLOI正源在JD,JD在初次短期集训结束后带出了一句经典名言: 那如果是在丛林里呢 这句话在短期内在全班范围内流传甚广,因此,\(GreatJungleLord\) 也因其幽默诙谐的形象赢得了大家的 ...