首页 > 其他分享 >学习笔记:斜率优化

学习笔记:斜率优化

时间:2023-10-10 13:55:46浏览次数:36  
标签:可以 笔记 times 斜率 最小值 优化 underline 式子

引入

有时候 我们会遇见一些 dp 式子

\[f_i=\min(f_j+a_i\times b_i)(j\leq i-1) \]

这些式子和 \(j\) 没有任何关系 可以前缀处理最小值 \(O(n)\) 快速解决
但是有些式子是这样的

\[f_i=\min(f_j+a_i\times b_j+c_i) \]

这种问题可以使用斜率优化至 \(O(n\log n)\)

例题

传送门
很容易看出来是 dp
多一维时间会非常麻烦 我们考虑费用预处理 就不用考虑启动时间了
总之 最后可以得到这个式子

\[f_i=f_j+t_i\times(c_i-c_j)+m\times (c_n-c_j) \]

时间复杂度 \(O(n^2)\)
其中 \(t\space c\) 是题目数组给出的前缀和数组
看到这个式子 想要优化一定要大力拆

\[f_i=f_j+t_i\times c_i-t_i\times c_j+m\times c_n-m\times c_j \]

难点就在于其中有 \(j\) 的项 观察可以发现它们的系数是固定的 这时候就是斜率优化了
把 \(f_j\) 扔到左边

\[f_j=f_i-t_i\times c_i+t_i\times c_j-m\times c_n+m\times c_j \]

整理得

\[\underline{f_j}_{\space y}=\underline{c_j}_x\times \underline{(t_i+m)}_k+\underline{f_i-t_i\times c_i-m\times c_n}_b \]

容易发现可以表示成一次函数的形式
这个一次函数的 \(k\) 是固定的
要 \(f_i\) 取到最小 就是让 \(b\) 取到最小
一个点对是 \((c_j,f_j)\)
数形结合 把点对拍上去
image
一条已知斜率的直线上 把这条直线往上移 碰到的第一个点取到函数最小值

那么 取到最小值的点有什么要求?
经过大量的手推归纳画图 可以得到一个点取到最小值的要求
image
只有当 \(k1< k0< k2\)时 这个点才能取到最小

然后会有很多点 有一些可能根本不会取到的点我们可以找到规律:
image
绿色的下凹包可以取到最小 红色的上凸包不可能取到最小
我们可以维护有效点 即保证任意两点的 \(k\) 值严格递增
因为这道题的 \(x\) 点保证递增 因此可以丢进队列里
然后 \(k\) 值也是递增的 可以直接使用单调队列维护
每次从队首更新即可
时间复杂度 \(O(n)\)

Code

int main()
{
	scanf("%d%lld",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%lld%lld",&t[i],&c[i]),t[i]+=t[i-1],c[i]+=c[i-1];
	l=r=1;//这里就是把f[0]=0 加进去 坐标 (0,0)
	for(int i=1;i<=n;i++)
	{
		while(l<r&&(f[q[l+1]]-f[q[l]])<=(c[q[l+1]]-c[q[l]])*(t[i]+m)) ++l;//把小于的当前斜率的点删掉 得到第一个大于当前斜率的点的左边的点
		f[i]=f[q[l]]+t[i]*c[i]-t[i]*c[q[l]]+m*c[n]-m*c[q[l]];
		while(l<r&&(f[i]-f[q[r]])*(c[q[r]]-c[q[r-1]])<=(f[q[r]]-f[q[r-1]])*(c[i]-c[q[r]])) --r;//维护斜率递增
		q[++r]=i;
	}
	printf("%lld",f[n]);
	return 0;
}

标签:可以,笔记,times,斜率,最小值,优化,underline,式子
From: https://www.cnblogs.com/g1ove/p/17754488.html

相关文章

  • 学习笔记427—Python Keras 报错AttributeError: 'Sequential' object has no attribu
    PythonKeras报错AttributeError:'Sequential'objecthasnoattribute'predict_classes'解决方法本文文要介绍Python中,使用Keras执行yhat_classes=model.predict_classes(X_test)代码报错:AttributeError:'Sequential'objecthasnoattribute'pr......
  • 学习笔记426—keras中to_categorical函数解析
    keras中to_categorical函数解析1.to_categorical的功能简单来说,to_categorical就是将类别向量转换为二进制(只有0和1)的矩阵类型表示。其表现为将原有的类别向量转换为独热编码的形式。先上代码看一下效果:fromkeras.utils.np_utilsimport*#类别向量定义b=[0,1,2,3,4,5,6,7......
  • 学习笔记425—train_test_split 函数介绍
    train_test_split函数介绍在机器学习中,我们通常将原始数据按照比例分割为“测试集”和“训练集”,从sklearn.model_selection中调用train_test_split函数 简单用法如下:X_train,X_test,y_train,y_test=sklearn.model_selection.train_test_split(train_data,train_targe......
  • 学习笔记424—%matplotlib inline的作用
    %matplotlibinline的作用%matplotlibinline是一个魔术命令(magiccommand),用于在JupyterNotebook或IPython环境中显示matplotlib图形的内嵌设置。当使用%matplotlibinline命令时,它会告诉Python在生成的图形直接嵌入到Notebook中的输出单元格中,而不是作为弹出窗口显示......
  • 学习笔记423—41.7%年化收益率 人工智能买股可以如此简单
    41.7%年化收益率人工智能买股可以如此简单学一门知识,充实自我掌握一项工具,让生活更美好~今天flare老师教大家AI选股,轻松搭建一个年化收益40%的机器学习选股策略—byflarezhao,转载请注明出处,原创不易,谢谢支持话不多说,先看策略的最终表现:2017年12月到2019年12月期间......
  • LntonGBS针对数据库删除级联数据后的无效数据进行的优化
    LntonGBS国标视频云服务可支持通过国标GB28181协议将设备接入,实现视频的实时监控直播、录像、语音对讲、云存储、告警、级联等功能,同时也支持将接入的视频流进行全终端、全平台分发,分发的视频流包括RTSP、RTMP、FLV、HLS、WebRTC等格式。同时LntonGBS平台也支持海康Ehome协议及SDK......
  • C# Winform ComboBox使用笔记
    ComboBox添加元素//添加元素到ComboBoxcomboBox1.Items.Add("元素1");comboBox1.Items.Add("元素2");comboBox1.Items.Add("元素3");for(inti=4;i<6;i++){comboBox1.Items.Add($"元素{i}");}//设置默认显示的项comboBox1.Selecte......
  • 【做题笔记】CF 1400-1600 构造题
    本人比较菜,所以做的rating很低/kk/kk/kk欢迎各位大佬嘲讽这个蒟蒻/kk/kk/kk/kk$*$表示看了题解才过的(所以你会发现这里的大部分题后面都会有$*$)实时通过率直接贴在后面当不看题解通过率稳定在\(50\%\)以上就弃坑。希望早日弃坑ABBCorBACB*题面中给了两种操作......
  • 组合数学习笔记
    一些式子\[(1+x)^\alpha=\sum_{i=0}\binom{\alpha}{i}x^i\\\binomnk=\fracnk\binom{n-1}{k-1}\\\binomnk=\binomn{k-1}+\binom{n-1}{k-1}\\\binomnm=(-1)^m\binom{m-n-1}m\\\binomnkk^{\underlinem}=\binom{n-m}{k-m}n^{\under......
  • JNI学习笔记
    1.使用Java程序调用C++函数步骤创建包含本地方法的Java类:packageorg.example;publicclassHelloWorld{static{System.loadLibrary("HelloWorld");}publicnativevoidprint();publicstaticvoidmain(String[]args){newHe......