DP斜率优化学习笔记

news/2024/9/12 13:21:03/文章来源:https://www.cnblogs.com/huhaoming/p/18373270

最后一次修改:2024.7.16 14:39 P.M By 哈哈铭

简介

“斜率优化”顾名思义就是用斜率进行优化,让 \(DP\) 的时间复杂度更优。
一般情况下,将动态转移方程化简后得到这样的关系式:

\[\frac{y_1-y_2}{x_1-x_2} \leq K \]

然后通过该式进行转移,以达到优化时间复杂度的目的。

小tip:推公式前可以先试着打出暴力。

例题(模板题)

P3195 [HNOI2008] 玩具装箱

题目大意

\(n\) 个玩具,第 \(i\) 个玩具价值为 \(c_i\)。要求将这 \(n\) 个玩具排成一排,分成若干段。对于一段 \([l, r]\),它的代价为 \((r − l + \sum _{i=l}^{r} c_i − L)^2\)。L 是给定常量,求分段的最小代价。

分析

首先,设 \(s_i\)\(\sum _{j=1}^{i} c_j\),又可以设一个简单易懂的状态:\(f_i\) 表示前 \(i\) 个玩具分段的最小代价,然后可以的到一个暴力的方程: \(f_i=\min_{1 \leq j <i}\left\{f_j+(r-l+s_i-s_j-L)^2\right\}\)。这个是 \(O(n^2)\)\(DP\)。带入另一个 \(k\),思考如何去最优解,考虑让它变形以符合斜率优化的公式。
化简过程省略……推起来太麻烦了
化简可得(当 \(1 \leq k < j \leq n\),同时,\(j\)\(k\) 更优时):

\[\frac{f_j-f_k+(s_j+j)^2-(s_k+k)^2}{s_j+j-s_k-k} \leq 2(s_i+i-L-1) \]

用单调队列进行优化就OK啦~

此处斜率越大越优。

见此图:

很明显,这里的斜率是越大越好(到 \(i\) 的)。

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e4+100;
ll n,L,f[N],s[N],q[N],head,tail;
inline ll mymin(ll x,ll y) {return x<y?x:y;}
inline double P(ll x) {return x*x;}
inline double X(ll x,ll y){return f[x]-f[y]+P(s[x]+x)-P(s[y]+y);}
inline double Y(ll x,ll y){return s[x]+x-s[y]-y;}
int main(){scanf("%lld%lld",&n,&L);for(int i=1;i<=n;i++){scanf("%lld",&s[i]);s[i]=s[i-1]+s[i];}f[0]=0;head=tail=0;for(int i=1;i<=n;i++){while(head<=tail&&X(q[head+1],q[head])<2*(s[i]+i-L-1)*Y(q[head+1],q[head])) head++;f[i]=f[q[head]]+P(i-q[head]+s[i]-s[q[head]]-L-1);while(head<=tail&&X(q[tail],q[tail-1])*Y(i,q[tail])>X(i,q[tail])*Y(q[tail],q[tail-1])) tail--;q[++tail]=i;}printf("%lld",f[n]);return 0;
}

[APIO2010] 特别行动队

题目大意

与上一题差不多,也是分若干段,但是求的是最大代价,代价的公式也不一样,肯定不一样啊,可是它仍然摆脱不了是一道斜率优化模板题的命运。

分析

这道题很简单。

首先,也是设 \(s_i\)\(\sum _{j=1}^{i} c_j\),然后得到一个 \(O(n^2)\) 的暴力 \(DP\)

其转移方程为:

\[f_i=\max_{1 \leq j <i}\left\{f_j+a\times (s_i-s_j)^2+b\times (s_i-s_j)+c \right\} \]

带入另一个 k,思考如何去最优解,考虑让它变形以符合斜率优化的公式。

化简过程省略……推起来太麻烦了 化简可得(当 \(1 \leq k < j \leq n\),同时,\(j\)\(k\) 更优时):

\[\frac{(f_j+a\times {s_j}^2)-(f_k+a\times {s_k}^2)}{s_j-s_k} \leq 2 \times a \times s_i+b \]

用单调队列进行优化就OK啦~

此处斜率越小越优。

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+100;
ll a,b,c,n,s[N],f[N],q[N],head,tail;
inline ll mymax(ll x,ll y) {return x>y?x:y;}
inline ll P(ll x) {return x*x;}
inline double slope(ll x,ll y){return 1.0*((f[y]+a*P(s[y]))-(f[x]+a*P(s[x])))/(s[y]-s[x]);
}
int main(){
//    freopen("t2.in","r",stdin);
//    freopen("t2.out","w",stdout);scanf("%lld",&n);scanf("%lld%lld%lld",&a,&b,&c);for(int i=1;i<=n;i++){scanf("%lld",&s[i]);s[i]=s[i-1]+s[i];}f[0]=0;for(int i=1;i<=n;i++){while(head<tail&&slope(q[head],q[head+1])>=2*a*s[i]+b) head++;f[i]=f[q[head]]+a*P(s[i]-s[q[head]])+b*(s[i]-s[q[head]])+c;while(head<tail&&slope(q[tail],i)>=slope(q[tail-1],i)) tail--;q[++tail]=i;}printf("%lld",f[n]);return 0;
}

征途

题目大意

其实与前两题差不多,只不过是要求了分的段数,公式也是光明正大地给出来了,其实同样简单,也是一道紫题

分析

这道题同样要一个前缀和,设为 \(v_i\) 吧。

然后设出状态:\(f_{i,j}\) 表示遍历到第 \(i\) 条路,走到第 \(j\) 天。

有一个 \(O(n^3)\) 的暴力可以得出。

考虑用斜率优化,因为里面总有奇奇怪怪的计算。

然后,可以得到一个动态转移方程,很简单,就不在此列出了。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3e3+50;
int n,m;
ll ans,f[N][N],v[N],sum[N],l[N],hd,tl;
double getK(int c,int i,int j) {ll x=f[i][c-1]+v[i]*v[i],xx=f[j][c-1]+v[j]*v[j];ll y=v[i],yy=v[j];return 1.0*(x-xx)/(y-yy);
}
int main(){
//    freopen("journey.in","r",stdin);
//    freopen("journey.out","w",stdout);scanf("%d%d",&n,&m);for(int i=1;i<=n;++i){scanf("%lld",&v[i]);v[i]=v[i-1]+v[i];}for(int i=1;i<=n;++i)f[i][1]=v[i]*v[i];for(int c=2;c<=m;++c){hd=tl=1;l[1]=c-1;for(int i=c;i<=n;++i){while(hd<tl&&getK(c,l[hd],l[hd+1])<2*v[i]) ++hd;f[i][c]=f[l[hd]][c-1]+(v[l[hd]]-v[i])*(v[l[hd]]-v[i]);while(hd<tl&&getK(c,l[tl],i)<getK(c,l[tl],l[tl-1])) --tl;l[++tl]=i;}}printf("%lld",m*f[n][m]-v[n]*v[n]);return 0;
}

然后就差不多了。

更多能练手的题目

[NOIP2018 普及组] 摆渡车

[ZJOI2007] 仓库建设

[CEOI2004] 锯木厂选址

$ \Large\mathcal{ Thank\ \ you\ \ very\ \ much!}$

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/785287.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LLM 推理 服务

目录vLLMPagedAttention:解决内存瓶颈vLLM 的安装与使用 vLLM 加州大学伯克利分校的研究者开源了一个项目 vLLM,该项目主要用于快速 LLM 推理和服务。 vLLM 的核心是 PagedAttention,这是一种新颖的注意力算法,它将在操作系统的虚拟内存中分页的经典思想引入到 LLM 服务中。…

批量图像识别的快速遍历技巧

本周我们来介绍一下如何快速地批量遍历图片列表找到图片对应的位置或对应关系,也很感谢Q群2群lincoln同学的分享,感兴趣的同学可以戳推文详细阅读~此文章来源于项目官方公众号:“AirtestProject” 版权声明:允许转载,但转载必须保留原链接;请勿用作商业或者非法用途一、前…

系统缓存可以删吗,删除系统缓存的方法有哪些

系统缓存是可以清理的,这些文件在长时间积累后可能会占用大量的磁盘空间,甚至影响电脑的性能。以下是一些清理C盘缓存的方法: 一、清理系统缓存 1.使用磁盘清理工具: 打开“此电脑”,右键点击C盘,选择“属性”。在“常规”选项卡中,点击“磁盘清理”。 系统将扫描C盘上的…

关于电脑晚上自动关机的问题,系统win11

前提:由于工作需要,有时需电脑在晚上仍能保持运行,但目前突然出现电脑晚上自动关机的情况,故需寻找解决方法。 解决方案:原文地址 方法:本次主要采取原文中所提及的方法二。 step1:搜索设备管理器step2:找到系统设备step3:在系统设备中找到Intel(R) Management Engine…

Vue 之混入(mixin)详细介绍

混入(mixin)提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项(如data、methods、mounted、filters等等)。 一、注册使用 1、在main.js中全局配置import mixin from ./mixinsVue.mixin(mixin)2、组件中配置 在日常的开发中,我…

Goby 漏洞发布|泛微 e-cology v10 appThirdLogin 权限绕过漏洞【漏洞复现】

漏洞名称:泛微 e-cology v10 appThirdLogin 权限绕过漏洞 English Name:Weaver e-cology v10 appThirdLogin Permission Bypass Vulnerability CVSS core: 7.5 漏洞描述: 泛微新一代数字化运营构建平台E10,是基于原eteams平台之上全新研发,同时融合了原E9产品的所有功能,…

[VS Code扩展]写一个代码片段管理插件(二):功能实现

@目录创建和插入代码片段代码片段列表代码片段预览代码片段编辑自定义映射默认映射自动完成项目地址 创建和插入代码片段 VS Code扩展提供了数据存储,其中globalState是使用全局存储的Key-Value方式来保存用户状态,支持在不同计算机上保留某些用户状态,详情请参考官方文档 若…

DLAFormer:微软提出多任务统一的端到端文本分析Transformer模型 | ICDAR 2024

论文提出新颖的基于Transformer的端到端方法DLAFormer,在统一的模型中集成多个文档布局分析任务,包括图形页面对象检测、文本区域检测、逻辑角色分类和阅读顺序预测。为了实现这一目标,将各种DLA子任务视为关系预测问题并提出了统一标签空间方法,使得统一关系预测模块能够有…

MySql Excel 数据导入

mysql工具:Navicat Premium 15 导入文件:file_Excel.xlsx 1.选择要导入到的表,右键选择导入向导,先择excel, 2.选择导入的数据文件,勾选excel的表名 3.设置字段选项,通配符 4.选择目标表,也可以自动新建表 5.字段对应关系展示,不匹配的会跳过 6.导入模式,追加或覆盖,…

Debian12+openresty1.25.3.2 部署 markdown在线编辑器 Editor.md

openresty的下载安装步骤参考: http://openresty.org/cn/linux-packages.html#debian 安装完成后:conf目录: /etc/openresty -> /usr/local/openresty/nginx/conf/html目录: /usr/local/openresty/nginx/htmlEditor.md 部署: cd /usr/local/openresty/nginx/htmlgit cl…

SLAB:华为开源,通过线性注意力和PRepBN提升Transformer效率 | ICML 2024

论文提出了包括渐进重参数化批归一化和简化线性注意力在内的新策略,以获取高效的Transformer架构。在训练过程中逐步将LayerNorm替换为重参数化批归一化,以实现无损准确率,同时在推理阶段利用BatchNorm的高效优势。此外,论文设计了一种简化的线性注意力机制,其在计算成本较…

神了!两个开源的高仿外卖项目!

大家好,我是 Java陈序员。 今天,给大家推荐两个高仿的外卖项目!关注微信公众号:【Java陈序员】,获取开源项目分享、AI副业分享、超200本经典计算机电子书籍等。高仿饿了么 项目简介 vue2-elm —— 一个基于 Vue2 + Vuex 构建具有 45 个页面的高仿饿了么项目,涉及注册、登…