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

斜率优化

时间:2023-10-12 19:44:20浏览次数:35  
标签:ix bx sum times 斜率 2as 优化 式子

斜率优化是一种优化 \(dp\) 的方法,不过在哪之前,我们需要引入一道例题。

点击查看代码 给你一个长度为 $n$ 序列 $A$,你需要把他分成若干段。定义第 $x$ 段的贡献为: $$a \times(\sum_{i=l_x}^{r_x} a_i))^2 +b\times \sum_{i=l_x}^{r_x} a_i+c$$ 你需要最大化贡献。 $a,b,c$ 为给定常数。 $n \leq 10^6$。

首先不妨先思考 \(O(n^2)\) 复杂度怎么做,我们不妨定义 \(f_{i}\) 表示以 \(i\) 结尾的最大贡献。显然存在 \(f_{i} = \max \limits _{j=1}^i \{ f_{i},f_{j-1}+a \times sum^2+b\times sum+c\}\) 。我们定义 \(sum\) 表示 \(\sum\limits_{k=j}^i a_k\)。显然,我们需要优化。

这时候引入斜率优化,不妨将转移点设为 \(k\),那么就会有这样一个式子。\(f_i=f_{k}+sum\times a+sum^2\times b+c\)。我们定义 \(s_i = \sum \limits _{j=1}^i a_j\)。原来的式子就会被我们变为: \(f_{i}=f_{k}+(s_{i}-s_{k-1})^2\times a+(s_{i}-s_{k-1})\times b+c\)。

这个式子是可以看做一个一次函数的,我们不妨设 \(s_{k-1}\) 为 \(x\),这样原来的式子就可以看为:

\(f_i=f_k+(s_i-x)^2\times a+(s_i-x)\times b+c\) 。

发现没有?我们把这个玩应打开。

\(f_{i}=f_{k}+as_i^2-2as_ix+x^2a+s_ib-xb+c\)。

我们其实不需要在乎 \(as_i^2+s_ib+c\) 这个东西,因为对于两个转移点 \(j,k\) 来说,这一个部分都是相同的,真正决定大小的显然并不是这一个地方。

也就是说,假设存在两个点 \(j,k\),如果 \(j\) 比 \(k\) 更优,就一定说明是 \(f_j+2as_is_j+as_j^2-bs_j \gt f_{k}+2as_is_k+as_k^2-bs_k\)
这个地方更优秀。
我们继续沿用刚才的思路,设 \(s_j,s_k\) 为 \(x_1,x_2\)。原来的式子就相当于
\(f_j+2as_jx_1+ax_1^2-bx\gt f_k+2as_ix_2+ax_2^2-bx_2\) 。

这时候就是斜率优化要做的事情了。我们可以把式子改成:

\(2as_ix_1-2as_ix_2\gt f_k-f_j+ax_2^2-ax_1^2-bx_2+bx_1\)
但是还没完,\(a\lt 0\)!!!
所以我们要变号。
\(2as_ix_1-2as_ix_2\lt f_k-f_j+ax_2^2-ax_1^2-bx_2+bx_1\)
也就是说 \(j\) 比 \(k\) 更优只需要满足这个式子就好了。由于我们 \(a\lt 0\),\(j,k\) 两点的式子又有单调性。所以本质上我们的最优答案就可以看成一个图。

不难发现,这是一个凸包,又具有单调性,我们可以使用单调队列维护。
具体的,我们每一次都是用队头更新答案(看图你会发现这道题这个东西单调递减)。在更新答案时,我们维护队头元素的点即可。使用我们前面推的式子即可轻松维护。同时,为了保证最优性,所以我们还需要在队尾也这样写。

Code
#include<bits/stdc++.h>
//fj-fk+a(sumj^2-sumk^2)-b(sumj-sumk)/2a*(sumj-sumk) <sumi 
using namespace std;
#define int long long
const int Maxn=2e6;
int n,aa,b,c,Sum[Maxn],per[Maxn],dp[Maxn],l,r,q[Maxn];
double slove(int j,int k){
  	return double( (dp[j]-dp[k]+aa*(Sum[j]*Sum[j]-Sum[k]*Sum[k])+b*(Sum[k]-Sum[j]))/double(2*aa*(Sum[j]-Sum[k])) );
}
signed main(){
	cin>>n;
	cin>>aa>>b>>c;
	for(int i=1;i<=n;i++){
		cin>>per[i];
		Sum[i]=Sum[i-1]+per[i];
	}
	//memset(dp,~0x3f,sizeof(dp));
	dp[0]=0;
	l=r=1;
	for(int i=1;i<=n;i++){
		while(l<r&&slove(q[l],q[l+1])<=1.0*Sum[i])l++;
		dp[i]=dp[q[l]]+(Sum[i]-Sum[q[l]])*(Sum[i]-Sum[q[l]])*aa+b*(Sum[i]-Sum[q[l]])+c;  
		while(l<=r&&slove(q[r-1],q[r])>=slove(q[r],i)) r--;
		q[++r]=i;
	}
	cout<<dp[n];
	return 0;
}

标签:ix,bx,sum,times,斜率,2as,优化,式子
From: https://www.cnblogs.com/Isharmla/p/17760402.html

相关文章

  • Java Stream 优化java代码
    使用strteam就是为了代码更加简洁,同时功能又不会收到影响,废话不多说使用原始流使用int、long和double等基本类型时,请使用IntStream、LongStream和DoubleStream等基本流,而不是Integer、Long和Double等装箱类型流。原始流可以通过避免装箱和拆箱的成本来提供更好的性......
  • 基于 ACK Fluid 的混合云优化数据访问(四):将第三方存储目录挂载到 Kubernetes,提升效率和
    作者:车漾前文回顾:本系列将介绍如何基于ACKFluid支持和优化混合云的数据访问场景,相关文章请参考:-基于ACKFluid的混合云优化数据访问(一):场景与架构-基于ACKFluid的混合云优化数据访问(二):搭建弹性计算实例与第三方存储的桥梁-基于ACKFluid的混合云优化数据访问(三):加速......
  • SQL 优化法则,就是这么简单
    这篇文章,是对SQL常用查询优化法则的总结,值得细看SQL作为关系型数据库的标准语言,是分析师必不可少的技能之一。SQL本身并不难学,编写查询语句也很容易,但是想要编写出能够高效运行的查询语句却有一定的难度。查询优化是一个复杂的工程,涉及从硬件到参数配置、不同数据库的解析器、优......
  • 第四节:Redis数据持久化机制(备份恢复)、缓存淘汰策略、主从同步原理、常见规范与优化
    一.数据持久化 1. 含义Redis提供了RDB和AOF两种持久化方式,默认开启的是RDB,如果需要AOF,需要手动修改配置文件进行开启。RDB:是一种对Redis存在内存中的数据周期性的持久化机制,将内存中的数据以快照的形式硬盘,实质上是fork了一个子进程在执行数据存储,采用的是二进制压......
  • 【RF分类】基于粒子群优化随机森林PSO-RF实现数据分类算法研究附matlab代码可直接运行
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 基于 ACK Fluid 的混合云优化数据访问(三):加速第三方存储的读访问,降本增效并行
    作者:车漾前文回顾:本系列将介绍如何基于ACKFluid支持和优化混合云的数据访问场景,相关文章请参考:基于ACKFluid的混合云优化数据访问(一):场景与架构基于ACKFluid的混合云优化数据访问(二):搭建弹性计算实例与第三方存储的桥梁在前一篇文章《搭建弹性计算实例与第三方存储的......
  • 性能测试过程中优化:
    1、登陆优化前:12000用户 120秒 99%的请求响应时间在9.8秒内优化后:12000用户120秒99%的请求响应时间在0.3秒内 优化内容:用户表增加了索引2、创建订单测试环境优化前后创建订单对比:优化前:1000订单 120秒  99%响应时间为14秒 如下: 优化后优化后:1000订单 120秒 ......
  • 视频监控系统/安防视频平台EasyCVR广场视频细节优化
    安防视频监控系统/视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。安防视频汇聚平台EasyCVR拓展性强,视频能力丰富,可实现视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警......
  • MySQL优化
    1.性能优化:1.1表结构优化(下述建议针对数据量巨大,每一点空间都需要节省的情况,当然在设计初期能考虑到以下建议最好)A:字段设计优化1.1.1整数类型:  1.对于整数int类型,数据量较大的情况下建议区分tinyint,int,bigint,三者所占据的空间有很大的......
  • 7min到40s:SpringBoot 启动优化实践!
    0背景公司SpringBoot项目在日常开发过程中发现服务启动过程异常缓慢,常常需要6-7分钟才能暴露端口,严重降低开发效率。通过SpringBoot的SpringApplicationRunListener、BeanPostProcessor原理和源码调试等手段排查发现,在Bean扫描和Bean注入这个两个阶段有很大的性能......