首页 > 其他分享 >斜率优化 DP

斜率优化 DP

时间:2024-04-08 20:12:33浏览次数:18  
标签:int 线段 斜率 DP slope1 slope2 优化 dp

对于这样一类方程

\(dp_i=\min \limits_{j=1}^{i-1}(dp_j-a_ic_j)\),其中 \(a,c\) 都为正整数且递增:

如果直接计算,时间复杂度为 \(\mathcal{O}(N^2)\)。

使用斜率优化,可以将时间复杂度将为 \(\mathcal{O}(N)\)。

在学习本节之前,请先学会单调队列,还要知道在平面直角坐标系中,斜率越小,直线(线段)越平;斜率越大,直线(线段)越陡

建模

我们将方程变形一下。去掉 \(\min\) 和移项,得到:

\(dp_j=a_ic_j+dp_i\)。

设 \(y=dp_j,k=a_i,x=c_j,b=dp_i\),得到:

\(y=kx+b\)。

我们称 \(k\) 为斜率,\(b\) 为截距。可以发现,最小的截距就是我们要求的 \(dp_i\)。

求一个 \(dp_i\)

假设我们已经求出了 \(dp_1 \sim dp_{i-1}\)。我们将这 \(i-1\) 个点的 \(x,y\) 坐标画到坐标系上。假设这些点的位置如下图。

因为 \(c\) 数组递增,所以每个点的 \(x\) 坐标递增,位置依次向右。

接下来,我们将斜率 \(k(a_i)=1\) 代入,生成直线:

\(b\) 值即为直线与 \(y\) 轴交点的 \(x\) 坐标。在上图中,点 \(2\) 的斜率最小。

假设我们再加入点 \(4\),图像如下:

此时,斜率为任意正整数时,\(4\) 的截距一定都比 \(3\) 的截距小,因此我们删除点 \(3\)。

我们再将每个点顺序连接:

然后删除点 \(3\):

可以发现,这些点组成了下凸壳,而点 \(3\) 形成了上凸壳而被删除了。

所以在求 \(dp_i\) 时,我们只需要将斜率 \(a_i\) 代入,在这些有用的点中找截距最小的点即可。

求所有 \(dp_i\)

刚才求出一个 \(dp_i\) 的时间复杂度为 \(\mathcal{O}(N)\),总时间复杂度依然为 \(\mathcal{O}(N^2)\)。如何优化?

注意条件中 \(a\) 数组也是递增的。在斜率逐渐递增时,能取到最小值的点是逐渐向右的。

比如上图的斜率为 \(1\),如果把斜率增加到 \(5\),则变成下图:

此时点 \(4\) 变为最优点。

因此,我们可以用单调队列来维护有用的点。如果新加的点与队尾的点不满足下凸壳,则弹出队尾。那么什么时候该弹出队头呢?

可以发现,最优点与其左侧点组成线段的斜率一定是小于 \(a_i\) 的,最优点与其右侧点组成线段的斜率一定是大于 \(a_i\) 的。如上面斜率为 \(1\) 的图中,最优点是 \(2\),线段 \(1 \to 2\) 的斜率小于 \(1\),线段 \(2 \to 4\) 的斜率大于 \(1\)。

因此,如果队列中前两点组成线段的斜率小于等于 \(a_i\),我们就把队头弹掉。满足条件后,队头的点即为最优点。

单调队列的时间复杂度为 \(\mathcal{O}(N)\)。

例题

给出两个序列 \(a,c\),保证这两个序列中的元素递增。求出另一个序列 \(dp\),使得:
\(dp_i=\min \limits_{j=1}^{i-1}(dp_j+a_ic_j)\)。
特别的,\(dp_1=0\)。
\(1 \le N \le 10^6,1 \le a_i,c_i \le 3 \times 10^6\),最后答案不会小于 \(9 \times 10^{18}\)。

我们用 \(X(a)\) 表示 \(a\) 点的 \(x\) 坐标,\(Y(a)\) 表示 \(a\) 点的 \(y\) 坐标。计算斜率时会用到小数,容易有精度错误,因此我们改用乘法。用 \(slope1(a,b)\) 表示线段 \(ab(a<b)\) 斜率的分子,\(slope2(a,b)\) 表示线段 \(ab(a<b)\) 斜率的分母,\(cmp1(a,b,k)\) 判断线段 \(ab\) 的斜率是否小于 等于 \(k\),\(cmp2(a,b,c,d)\) 判断线段 \(ab\) 的斜率是否大于等于线段 \(cd\) 的斜率。

最后代码如下。

#include<cstdio>
#define UP(i,a,b) for(i=a;i<=(b);++i)
#define DN(i,a,b) for(i=a;i>=(b);--i)

typedef long long ll;

const int N=1e6+5;
int a[N],c[N],n,q[N],h,t;
ll dp[N];

ll X(int x){
	return c[x];
}
ll Y(int x){
	return dp[x];
}
ll slope1(int x,int y){
	return Y(y)-Y(x);
}
ll slope2(int x,int y){
	return X(y)-X(x);
}
bool cmp1(int x,int y,int k){
	/*slope1(x,y)/slope2(x,y)<=k*/
	/*slope1(x,y)<=k*slope2(x,y)*/
	return slope1(x,y)<=k*slope2(x,y);
}
bool cmp2(int x,int y,int e,int f){
	/*slope1(x,y)/slope2(x,y)>=slope1(e,f)/slope2(e,f)*/
	/*slope1(x,y)*slope2(e,f)>=slope1(e,f)*slope2(x,y)*/
	return slope1(x,y)*slope2(e,f)>=slope1(e,f)*slope2(x,y);
}
int main(){
	int i,j;
	scanf("%d",&n);
	h=t=1;
	UP(i,1,n){
		scanf("%d%d",a+i,c+i);
		/*弹掉队头斜率<=a[i]的*/
		while(h<t&&cmp1(q[h],q[h+1],a[i])){
			++h;
		}
		j=q[h];
		/*此时j即为最优点*/
		dp[i]=dp[j]-1ll*a[i]*c[j];
		/*弹掉 队尾两点线段斜率>=线段(队尾点->i)斜率的点*/
		while(h<t&&cmp2(q[t-1],q[t],q[t],i)){
			--t;
		}
		q[++t]=i;
		printf("%lld%c",dp[i]," \n"[i==n]);
	}
	return 0;
}

标签:int,线段,斜率,DP,slope1,slope2,优化,dp
From: https://www.cnblogs.com/lrxmg139/p/18122430

相关文章

  • 小红不想做完全背包 (hard)(DP)--牛客周赛 Round 39-D
    #include<bits/stdc++.h>usingnamespacestd;#defineintlonglong#defineendl'\n'#defineinf1e18constintmod=1e9+7;constintN=2005;//typedef__int128lll;//typedefunsignedlonglongull;intn,p;inta[N],dp[N];voidsolve(){......
  • Linux命令之lldptool命令
    LLDP是一个数据链路层发现协议,LLDP协议使得接入网络的一台设备可以将其主要的能力,管理地址,设备标识,接口标识等信息发送给接入同一个局域网络的其它设备。lldptool工具采用的是LLDP协议,一般我们使用lldptool是为了得到设备的物理拓扑结构以及管理配置信息,比如说,和eth1网口相连的网......
  • android 内存优化
    什么是内存泄漏?如果一个无用对象(不需要再使用的对象)仍然被其他对象持有引用,造成该对象无法被系统回收,以致该对象在堆中所占用的内存单元无法被释放而造成内存空间浪费,这中情况就是内存泄漏。在Android开发中,一些不好的编程习惯会导致我们的开发的app存在内存泄漏的情况。下......
  • 状态压缩dp——动物园
    题目描述新建的圆形动物园是亚太地区的骄傲。圆形动物园坐落于太平洋的一个小岛上,包含一大圈围栏,每个围栏里有一种动物。如下图所示:你是动物园的公关主管。你要做的是,让每个参观动物园的游客都尽可能高兴。今天有一群小朋友来到动物园参观,你希望能让他们在动物园度过一段美好的......
  • JUC:ThreadPoolExecutor线程池的使用方法
    文章目录ThreadPoolExecutor线程池状态构造方法Executors工厂方法newFixedThreadPoolnewCachedThreadPoolnewSingleThreadExecutor提交任务方法关闭任务方法ThreadPoolExecutor线程池状态线程池用高三位表示状态,第一位为符号位。TERMINATED>TIDYING>STOP>......
  • 【论文复现|智能算法改进】融合多策略的黄金正弦灰狼优化算法
    目录1.算法原理2.改进点3.结果展示4.参考文献1.算法原理【智能算法】灰狼算法(GWO)原理及实现2.改进点收敛因子非线性调整策略GWO算法的探索和开发能力很大程度上依赖于A的取值,当|A|>1时,灰狼群体通过扩大搜索范围继续搜寻猎物,即全局搜索;而当|A|<1......
  • 【智能算法】减法平均优化器(SABO)原理及实现
    目录1.背景2.算法原理2.1算法思想2.2算法过程3.结果展示4.参考文献1.背景2023年,PTrojovský等人受到数学计算启发,提出了减法平均优化器(Subtraction-Average-BasedOptimizer,SABO)。2.算法原理2.1算法思想SABO利用多个智能体的减法平均值来更新种群成员在搜索......
  • 如何避免WordPress中文乱码现象
    在使用WordPress网站的过程中,很多用户都会遇到中文乱码的问题。中文乱码会给用户阅读和浏览网站带来困扰,也可能影响网站的用户体验和搜索引擎优化。在本篇文章中,我们将介绍一些解决WordPress中文乱码问题的方法,并提供具体的代码示例。1、设置数据库字符集:首先,要确保数据库字符集......
  • WordPress访问不了?快速解决方法大揭秘!
    《WordPress访问不了?快速解决方法大揭秘!》WordPress作为一个流行的内容管理系统,被广泛应用于网站建设领域。然而,有时候我们可能会遇到WordPress网站无法访问的情况,这个问题如果不及时处理,会影响网站的正常运行,进而影响用户体验。本文将探讨常见的WordPress网站无法访问问题,并提供......
  • WordPress网站乱码怎么办?快速解决方案
    在使用WordPress建立网站的过程中,有时候会遇到网站页面出现乱码的情况,这会影响用户体验和网站的可读性。造成网站乱码的原因可能有很多,比如字符编码设置不正确、插件冲突、主题代码问题等。本文将为您介绍一些快速解决WordPress网站乱码问题的具体方法,并提供相应的代码示例。1.......