斜率优化DP

[模板] 斜率优化Dp详解 算法简介今天xinyue讲了斜率优化,全程懵逼,居然还有这么牛逼的东西。 于是与achen讨论了一下,总结一些东西。 斜率优化Dp其实是单调队列的推广,单调队列、旋转卡壳、斜率优化都利用了单调性降低时间复杂度。算法简介举个例子 有些动规状态转移方程可以写成 f[i]=min/max{f[j]+…+x[i]},省略号中只有与j有关的变量。 我们就可以用单调队列进行优化,使O(n^2)降为O( 阅读详情

引用一片经典的文章:http://blog.sina.com.cn/s/blog_508dd1e60100tvk0.html

  最近发现HDU上的题目ms比POJ上的好些似的, 因为每次都是一道题搞一天。 也说明我真的还是很菜啊。 昨天搞了一道题,一道最短路的题目,弄了一天。其实最主要的原因是没有搞清楚Dijkstra、SPFA、Bellman_ford这几个最短路算法的复杂度。这里作个总结,数组实现的Dijkstra,复杂度为O(N^2);用优先队列优化的Dijkstra复杂度为O(ElogE),但是图需要用邻接矩阵实现;Bellman_ford,O(VE);SPFA,O(KE),K<<V; HDU 3349,给出一张图,题意是可以选择一条边进行减半,其他的不能变,求从S到T的最短路。直接枚举每条边,然后进行Dijkstra,由于题意中的N给了1e5,N^2的算法显然会超时,分析一下可知,超时的原因是每次只枚举了一条减半的边,但是重复求了其他点的最短路,一个优化是将S到每个点的最短路保存在一个数组里,然后求出每个点到T点的最短路。依次枚举每条边,min = MIN(sDis[i] + tDis[j] + cost[i][j]/2 ),<i,j> ;求两次最短路的时候,可以用Heap+Dijkstra, 当然更容易实现的自然是SPFA。 一开始没有想到用SPFA,一直过不了,调了半天,一直WA。 然后就是看到了网上有人用SPFA,换了SPFA,但是没有考虑起点和终点是同一个点的情况,各种WA。 最后msWA了20+次,才AC, 汗。。。。。

       今天做了一道DP的题目,题意如下:
【题目大意】
有N个数,现要将它们分成连续的若干段,每段的代价为(∑Ci)^2+M,求最小的代价。
【题目分析】
容易得到这样的一个动态规划算法:
令dp[i]表示前i个数分成若干段的最小代价,能得到一个经典的动态转移方程: 
dp[i]=  Min  (dp[j] + Cost(j+1,i))+M,0<=j<i。 
其中Cost(a,b)表示把a..b这些数分成一段的费用。
这个算法的时间复杂度是O(N^2)。 这题N有500000,必须优化。
我们看到Cost(j+1,i)。如果预处理出1..i的和,记为s[i],那么Cost可以表示为(s[i]-s[j])^2。
将它展开并且代入转移方程中可以得到: dp[i]= Min (dp[j] + s[i]^2 -2s[i]*s[j] +s[j]^2)+M。
因为s[i]^2是只和i有关的,可以移到Min的外面,得到
dp[i]= Min (dp[j] -2*s[i]*s[j] +s[j]^2) + M + s[i]^2。
现在我们单独考虑Min()里面的内容。
如果我们设 k=2*s[i],x=s[j],y=dp[j]+s[j]^2的话(注意将和i有关的量以及和j有关的量结合到一起)
再令G=dp[i],那么将得到:
G=-k*x+y。
移项得:
y=k*x+G。
看到这个式子,知道斜率优化的朋友显然可以做出来了。
这里我讲讲何谓斜率优化。
得到这个式子之后,我们可以看到,k是一个常数(由当前枚举的i在O(1)时间内计算得出)。将这个式子看成是一个直线的函数表达式的话,k就是斜率,也就是说这是一个斜率固定的直线。
y和x则是和j有关的常量。而j的这些值应该都已经在之前计算过了。(因为j<i)
这个式子中,G是未知的,G和y以及x有关。
如果我们把每个j对应的x和y值看成一个坐标系中的点的话。
那么当我们枚举到i时,坐标系中就有一系列的点。
对于每个点,做一条斜率为k的直线,就能得到一个G的值。G的值为这条直线与y轴交点的纵坐标。
我们可以看到,实际上,如果我们让G的值由负无穷变化到正无穷,相当于一条直线,它满足斜率为k,然后从坐标系的下方慢慢地向上平移到坐标系的上方。
那么,我们要找到,G的最小值,就是在这个过程中,这条直线所碰到的第一个点!
而这个点,必然是这个点集的凸包上的点。(不知道凸包概念的去baidu一下好了)
再加上很关键的一点。随着i的增加,点的坐标是单调不下降的(s[i]),直线的斜率也是单调不降的(2s[i])!
满足这两个单调性,我们就可以利用单调队列,来维护一个凸壳。因为我们要找G的最小值,所以要维护一个下凸壳。方法和之前那篇数形结合题一样, 类似Garham求凸包的算法 。
之所以可以用单调队列是因为坐标和斜率都满足单调性的话,可以证明每个点如果不是某个i的最优决策,也不能会是之后的i的最优决策,可以被抛弃。
因为每个i只会进出队列一次,所以时间复杂度降为O(N),只需要保存单列就可以,空间复杂度为O(N),比较完美地解决了这个问题。 


附图:



其中绿色部分:类似Garham求凸包的算法:一个一个按逆时针来,加入j1, j2. j3. j4,再加入j5时,向量差乘,发现j5在s射线j3j4的右边,结果为负值,就把j4去掉,继续j6j7j8....

其中背景绿色的部分的简单证明:G=y-kx,对于两个点G1=y1-kx1, G2=y2-kx2,G2在G1点后面出现,也就是说y1<y2, x1<x2,对于一个较小的k尚且有y1-kx1>y2-kx2,即k(x2-x1)>y2-y1,当k增大时,该式当然成立。


而下面代码中之所以能够通过比较相邻的j方式来实现,是因为对于每一个k(或者说没一个i),关于j的函数图像都是 U 字形的。而随着k(或者说i)的增大,这个U字形的极值点也是在不断增大的。(可以参考http://wenku.baidu.com/view/d3d979dcd15abe23482f4d58.html 里面的第一段证明)


附 HDU 4258:Covered Walkway的题目和代码:

Covered Walkway

Time Limit: 30000/10000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 350    Accepted Submission(s): 140


Problem Description
Your university wants to build a new walkway, and they want at least part of it to be covered. There are certain points which must be covered. It doesn’t matter if other points along the walkway are covered or not. 
The building contractor has an interesting pricing scheme. To cover the walkway from a point at  x to a point at  y, they will charge  c+( x- y) 2, where  c is a constant. Note that it is possible for  x=y. If so, then the contractor would simply charge  c. 
Given the points along the walkway and the constant  c, what is the minimum cost to cover the walkway?
 

Input
There will be several test cases in the input. Each test case will begin with a line with two integers,  n (1≤ n≤1,000,000) and  c (1≤ c≤10 9), where  n is the number of points which must be covered, and  c is the contractor’s constant. Each of the following  n lines will contain a single integer, representing a point along the walkway that must be covered. The points will be in order, from smallest to largest. All of the points will be in the range from 1 to 10 9, inclusive. The input will end with a line with two 0s.
 

Output
For each test case, output a single integer, representing the minimum cost to cover all of the specified points. Output each integer on its own line, with no spaces, and do not print any blank lines between answers. All possible inputs yield answers which will fit in a signed 64-bit integer.
 

Sample Input
  
10 5000 1 23 45 67 101 124 560 789 990 1019 0 0
 

Sample Output
  
30726
 

Source

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
template <class _Tp> _Tp inline sqr(_Tp a) { return a*a;}

LL GetLL() {
	char ch = ' ';
	while(ch < '0' || ch > '9')
		ch = getchar();
	LL x = 0;
	while (ch >= '0' && ch <= '9')
		x = x * 10 + ch - '0',ch = getchar();
	return x;
}
#define MAXN 1000005

struct point{
	LL x,  y;
	point() {x=y=0;}
	point(LL a, LL b) {x=a; y=b;}
};
LL multi(point o, point a, point b){
	return (a.x-o.x)*(b.y-o.y) - (a.y-o.y)*(b.x-o.x);
}

LL dp[MAXN];
point q[MAXN]; int head, tail;

int n, c;
LL x[MAXN];

int main()
{
	while( scanf("%d%d", &n, &c), n||c ){
		memset(x, 0, sizeof(x));
		memset(dp, 0, sizeof(dp));

		for(int i=0; i<n; i++)
			//scanf("%I64d", &x[i]);
			x[i] = GetLL();      //这两句话意思一样,解释见文章末尾

		head = tail = 0;
		q[tail ++] = point(x[0], sqr(x[0]));
		dp[0] = c;
		for(int i=1; i<n; i++){
			point pp(x[i], dp[i-1] + sqr(x[i]));
			while( head+1<tail && multi( q[tail-2], q[tail-1], pp ) < 0 )   tail --;   //凸包 加点
			q[tail ++] = pp;

			while( head+1<tail && q[head].y - 2*x[i]*q[head].x >= q[head+1].y - 2*x[i]*q[head+1].x )  // y-kx 去点
				head ++;
			dp[i] = q[head].y - 2*x[i]*q[head].x + x[i]*x[i] + c;
		}
		printf("%I64d\n", dp[n-1]);
	}
	return 0;
}

===============================================================================================================

顺便还有个输入输出的优化:

LL GetLL() {
	char ch = ' ';
	while(ch < '0' || ch > '9')
		ch = getchar();
	LL x = 0;
	while (ch >= '0' && ch <= '9')
		x = x * 10 + ch - '0',ch = getchar();
	return x;
}

用GetLL代替scanf("%lld", &),将2859MS的代码降低到了1968MS,(读写次数与时间复杂度比例1:1),而后面玩扑克牌的那道题(读写次数与时间复杂度比例1:800),也能用类似的方法将时间从4281MS降低到4031MS。

利用的就是getchar() 的神速度....

斜率优化动态规划DP 斜率优化DP 立即下载

相关推荐

避坑指南:海康MV_CC_SetIntValue接口的7个典型报错解决方案

本文深度解析海康工业相机SDK中MV_CC_SetIntValue接口的典型报错,提供7个实战解决方案。针对MV_E_CALLORDER、MV_E_PARAMETER等高频错误码,从设备状态、参数值域、依赖关系等核心约束入手,给出清晰的诊断流程与根治代码,帮助开发者构建健壮的参数设置模块,提升开发效率。

y2z3a4b5c的博客 1078

[学习笔记]斜率优化dp 总结

我们学过不少优化类的算法了,大部分都是基于凸函数的性质给出的优化,比如Slope Trick,Wqs二分,又比如今天的斜率优化(不知道什么时候会有空把Slope Trick写掉)当dp式子满足cy−cxby−bx≤−aiby​−bx​cy​−cx​​≤−ai​的时候,我们要维护的是一个下凸包i

sophilex的博客 2140

FAST-LIO2实战:如何在无人机上部署并实现厘米级定位(附ROS配置全流程)

本文详细介绍了如何在无人机上部署FAST-LIO2激光雷达惯性里程计系统,以实现厘米级精确定位。内容涵盖从硬件选型(如激光雷达与机载计算机)、软件环境配置(ROS Noetic)、传感器标定,到FAST-LIO2参数调优、与PX4飞控集成以及实际飞行测试的全流程。重点解决了实时定位中的外参标定、数据同步等关键问题,为无人机在无GPS或复杂光照环境下提供稳定可靠的定位解决方案。

weixin_29062865的博客 250

学习笔记——斜率优化dp

优异算法,动态规划。掌上明珠,斜率优化。确实,斜率优化很重要,并且通常式子比码长,脑袋想不清。新手易懂的斜率优化博客来啦!注:其中全部图片均为手绘,不喜勿喷。

Young_20220202的博客 801

pytorch-cifar100学习资料汇总 - 基于PyTorch的CIFAR-100图像分类实践

pytorch-cifar100是一个基于PyTorch实现CIFAR-100数据集图像分类的开源项目。该项目实现了多种经典的深度学习网络模型,如ResNet、DenseNet、VGG等,为开发者提供了在CIFAR-100数据集上进行图像分类实验的代码范例。pytorch-cifar100项目为我们提供了在CIFAR-100数据集上进行图像分类实验的完整代码实现。无论你是想要学习PyTorch的使用,还是研究不同网络模型在CIFAR-100上的表现,这个项目都是一个很好的起点。

helloaiworld的博客 1123

Fastp实战指南:高效处理fastq数据的质控技巧

本文是Fastp实战指南,详细介绍了如何使用Fastp工具高效处理fastq数据的质控技巧。从数据清洗的必要性、基础命令解析,到高级参数定制、UMI数据处理及批量自动化流程,提供一站式解决方案。Fastp以其“All-in-One”的快速质控能力,帮助用户确保测序数据质量,为后续生物信息学分析奠定可靠基础。

weixin_29254029的博客 389

【学习笔记】动态规划—斜率优化DP(超详细)

【学习笔记】动态规划—斜率优化DP(超详细) 【前言】 第一次写这么长的文章。 写完后感觉对斜优的理解又加深了一些。 斜优通常与决策单调性同时出现。可以说决策单调性是斜率优化的前提。 斜率优化 \(DP\),顾名思义就是利用斜率相关性质对 \(DP\) 进行优化。 斜率优化通常可以由两种方式来理解,需要灵活地运用数学上的数形结合,线性规划思想。 对于这样形式的 \(dp\) 方程:\(d...

aiauw80822的博客 1200

数据分析案例-2024年裁员数据集可视化分析

本实验数据集来源于Kaggle,原始数据集为2020-2024年裁员数据,共有3577条,12个变量,该数据集提供了不同公司的裁员信息。它包括以下几栏:Company:裁员发生的公司名称。Location_HQ:公司总部位置。Industry:公司所属的行业或部门。Laid_Off_Count:公司解雇的员工数量。Percentage:公司员工被解雇的百分比。Date:裁员发生的日期。Source:信息来源网址。Funds_Raised:公司募集资金的信息。

m0_64336780的博客 1万+

DP优化之斜率优化

如题

INF_512的博客 1487

【YoloV11改进策略】基于流形约束超连接(mHC)增强YoloV11全局特征提取能力|独家复现|梁文峰署名论文

论文标题:流形约束超连接 (Manifold-Constrained Hyper-Connections, mHC)核心问题:针对超连接 (Hyper-Connections, HC) 扩展残差流宽度时破坏恒等映射、引发训练不稳定性和高内存开销的问题,提出一种约束性框架。目标:恢复残差连接的稳定性与可扩展性,同时保持HC的性能增益。基准模型:基于DeepSeek-V3的MoE架构,进行了3B、9B、27B模型的实验验证。论文图示mHC 是一个通用的HC扩展框架。

m0_47867638的博客 1349

Autosar配置——导入DBC后配置SecOC同步报文和同步请求报文

在Autosar中,安全性是一个重要的考虑因素,而SecOC(Secure On-Board Communication)是一种用于保护通信数据完整性和安全性的安全机制。在上述示例中,我们配置了同步报文和同步请求报文的属性。接下来,我们需要在Autosar中配置同步报文和同步请求报文。同步报文用于在通信双方之间同步SecOC状态,而同步请求报文用于请求SecOC的状态信息。通过以上配置,我们成功地导入了DBC文件,并在Autosar系统中配置了SecOC同步报文和同步请求报文。希望以上信息对您有所帮助!

CyberSphinx的博客 649

【详解】斜率优化 DP

斜率优化详解+凸包详解

2403_87021226的博客 2344

vectorCast——Probe point 功能实现故障注入,局部变量打印,断点调试。

选择一个测试用例,选择coverage窗口进行查看。点击edit probe point,如图所示绿色的小圆圈。 选代码中选择需要打断点的地方进行点击。黑色的小圆点都可以选。 点击黑色小圆点,小圆点变绿,表示打断点成功。 此时就可以根据自己的需求在打断点的位置编写一些C语言的命令语句。 点击编译,成功会弹出窗口显示编译成功,失败会在下方报错error,并显示错误的原因。 点击应用保存,选择yes to all就可以了。 点击用例执行就可以看到打断点情况下的执行结果了。

weixin_59334478的博客 2068

DP斜率优化

DP斜率优化   DP斜率优化,实际上就是以斜率作为比较的基准,使用单调队列优化的方法,使用斜率优化的问题应当具有这样的特征——状态转移方程是一个关于dp[i]和dp[j]的线性方程,也即dp[i]与dp[j]具有线性关系。   这样我们在求解dp[i]时,实际上就是求解一个点(dp[j],j),使得过该点的dp[i]的值最小,由于斜率是固定的,这导致我们只需要寻找与dp[j]的点形成的凸包相切的那一点作为最优转移点即可,实际求解过程中,我们只需要用单调队列维持边界上的点,再用二分查找的方式确定相切的点即可

qq_37957064的博客 668

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

斜率优化 DP 总结

一般来说,斜率优化DP 的题目会比较复杂,给的信息比较多,需要抽象出 准确的转移式。发现若当前新加入的点与队尾的连线斜率小了,可以把队头出队,直到斜率单调。时,提前计算本次启动 对 后面所有任务费用的增量,直接加到。这就是 斜率优化 DP 的第一步,写成朴素的 DP 转移式,同样是 “一段一段” 的 DP,唯一需要注意的是决策上界。顾名思义,运用数形结合的思想,将 DP 中求解的。的直线,我们考虑找到使得 截距 最大的那个决策点。但本题有个不太好处理的点,机器启动的时间。

qq_56326461的博客 417

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

DP 优化二:斜率优化 DP

本文介绍了任务安排问题的动态规划解法及其优化方法。首先通过P2365任务安排问题展示了基础$O(n^2)$DP解法,采用费用预先处理思想将状态转移优化为单维。随后针对P10979任务安排2的$n≤3×10^5$数据规模,引入斜率优化DP技术。该方法将转移方程转化为一次函数形式,通过维护下凸包来快速确定最优决策点。文章详细分析了点与斜率的关系,证明了上凸包中的中间点不会成为最优解,从而提出使用队列维护下凸包的有效算法。这种优化方法将时间复杂度降为$O(n)$,适用于大规模数据情况。

cwplh的博客 938

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

论斜率优化dp

首先,加上机器启动时间,我们直接把之后所有的费用系数求和再乘以机器启动时间,这就是无后效性。但是呢,我们可以把若干个任务并做一个,费用系数,完成耗时都求和,只是不需要多次启动机器了。那么哪个点离直线最近呢,显然是连接两条斜率分别大于和小于当前直线的线段的点。因为之前任务已经花费的时间会算到当前任务上,且启动机器时间已经算过了。对于新插入的点,肯定是斜率越小越好,这下动态维护下凸包也可以一并解决。显然的,一个下凸包,我们动态维护凸包,这样就有了单调性。的时间启动机器,做每个任务都需要一定时间,假设在。

senlinguyvan1的博客 1318

【总结】斜率优化DP

于是,XSC062开始写总结。 斜率优化DP的本质 前置芝士 单调队列优化DP(夹带私货) 正文 我没有脑子QwQ 我们以一道题为例。 例题一:打印文章 双倍经验 三倍经验 明显DP。 那么DP式就是: fi=min⁡{fj+(si−sj)2+M}=min⁡{fj+si2−2×si×sj+sj2+M}=min⁡{fj−2×si×sj+sj2}+si2+M \begin{aligned} f_i&=\min\{f_j+(s_i-s_j)^2+M\} \\ &=\min\{f_j+{s_i}^

XSC062 的博客 342

斜率优化dp

斜率优化dp 一种和数学联系很大的\(dp\)的优化方式 做题时的思路一般如下: 如果做\(dp\)题时,这道题转移\(dp[i]\)的值时需要用到前面的决策\(dp[j]\)的值,且出现了i与j的乘积时,考虑斜率优化 做题步骤如下: 一.根据题意,灵活列出一般的不含前缀和优化的\(dp\)方程,然后根据\(dp\)方程的特点,加上前缀和优化(其它的前缀优化的题也可以这么做) 二.将只与...

dbp123123的博客 225

斜率优化dp学习

参考:传送门 在做dp的时候一个状态i需要从0~i-1的状态中选择最优状态来进行转移,而单纯的这样转移,时间复杂度是O(n^2)的,使用斜率优化dp可以将时间复杂度降低到O(n)或者O(nlogn)。 如果状态i从一个状态转移j比从另一个状态k转移好,那么他们之间肯定会存在一个包含i,j,k的不等式,如果这个不等式能够化成左边只和j,k有关的斜率,右边只和i又管,那么就是j,k之间的某种斜率满...

yypurpose的博客 371
上一篇: LCA 与 RMQ
下一篇: poj 2823 (单调队列)
Balloons2012
博客等级 码龄14年 9粉丝 38原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值