斜率优化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 立即下载

相关推荐

手把手教你用SysMax桥接软件搞定CANoe、INCA和刷写工具(附驱动配置避坑点)

本文详细介绍了如何使用SysMax PCAN FD桥接软件实现CANoe、INCA和刷写工具的无缝对接,提供从驱动配置到多软件协同的全链路指南。重点解析了驱动安装避坑点、CANoe配置技巧、INCA集成方法以及刷写工具链优化方案,帮助汽车电子工程师构建高效开发环境。

weixin_30500105的博客 390

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

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

sophilex的博客 2140

STM32-DAC定时器触发三角波生成【频率与幅度精准控制】

本文详细介绍了STM32 DAC定时器触发三角波生成的原理与实现方法,涵盖硬件配置、频率与幅度精准控制技巧及代码实现。通过定时器触发DAC模块,可灵活调节三角波的频率和幅度,适用于信号发生器等高精度应用场景。

weixin_29161785的博客 452

学习笔记——斜率优化dp

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

Young_20220202的博客 801

OpenHarmony 5.1 RK3568 开发板烧录:从源码编译到镜像写入的 6 步实战

本文详细解析了OpenHarmony 5.1在RK3568开发板上的全链路开发流程,包括环境搭建、源码编译、镜像烧录等6个关键步骤。通过实战指南和避坑技巧,帮助开发者快速掌握OpenHarmony系统的烧录与定制能力,提升物联网设备开发效率。

weixin_33722405的博客 343

K230开发板实战:YOLOv8n模型部署全流程(附常见报错解决方案)

本文详细介绍了在K230开发板上部署YOLOv8n模型的完整流程,包括模型选型、配置文件优化和运行时调优。特别针对常见的'生成部署文件异常'等问题提供了实用解决方案,帮助开发者高效完成嵌入式AI模型的部署与优化。

g8f9d0s1a2的博客 1048

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

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

aiauw80822的博客 1200

计算机网络之NAT的解释与实验配置

NAT 静态NAT 动态NAT easy_ip NAT服务器映射

爱学习的JackYang的博客 1916

DP优化之斜率优化

如题

INF_512的博客 1487

Wonderware Intouch 2014R2 SP1 安装教程

下载Wonderware System Platform 2014R2 SP1 and Intouch 2014R2 SP1的安装压缩包,如下 软件的下载连接地址如下: https://pan.baidu.com/s/1a2GnI_nfT3vK1l49B94FIQ, 提取码:6ec6 或者直接微信扫描下面的二维码 管理员运行下面的setup.exe可执行程序, 进入安装,选择Product Based Selection, 自定义选择需要安装的程序,如下: 普通的Into

工控先生 3万+

Ubuntu零基础入门到精通【3.10讲】:旧版本 Ubuntu 升级与迁移路线:从 20.04 到 24.04 的完整实战指南

🏆 本文收录于 《滚雪球学 Ubuntu》 专栏。 本专栏面向有一定计算机基础,但尚未系统学习 Linux / Ubuntu 的读者,采用“滚雪球式学习法”:先装好、再会用、再理解、再优化、再实战,带你从第一次进入 Ubuntu 桌面 / 终端开始,逐步掌握 Ubuntu 的日常使用、命令操作、软件安装、系统配置、开发环境搭建与服务器部署能力。

**My Coding Family** 1246

【详解】斜率优化 DP

斜率优化详解+凸包详解

2403_87021226的博客 2344

提示词驱动的智能合同生成与审核

第1章:核心概念与背景 1.1.1 问题背景 1.1.1.1 合同生成与审核的需求 合同作为商业和法律领域中的基本工具,其生成和审核过程至关重要。传统的合同生成往往依赖于法律专业人士的手工撰写,这不仅耗时耗力,而且容易出现错误。此外,合

AI天才研究院 999

DP斜率优化

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

qq_37957064的博客 668

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

visio安装包

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

斜率优化 DP 总结

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

qq_56326461的博客 417

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

DP 优化二:斜率优化 DP

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

cwplh的博客 938

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

论斜率优化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、付费专栏及课程。

余额充值