斜率优化DP简单总结“土地购买”题解

news/2024/10/7 6:41:03

今天刚刷完了斜率优化DP,简单从头回顾一下。

\[首先,能写出DP方程应该是最重要的,毕竟斜率只是用来优化的 \]

那么一个DP方程能用斜率优化,具备一种形式:

\[f[i]+s1[i]+A[i]*B[j]=f[j]+s2[j] \]

其中,f[i]表示所求值,(s1[i]、A[i])与(s2[j]、B[j])分别表示只与i或j有关的一个表达式(可以是只有常数项)。

然后就可以建立一个横坐标为B[j],斜率为A[i],纵坐标为f[j]+s2[j]的函数。如果横坐标有单调性,那么只需单调队列保留一个凸壳或凹壳即可(任务安排2),否则就像需要支持任意插入、查询(任务安排3、4)。


基本形式大概就是上面那样,接下来从题中看点特别的。

1、任务安排系列

  • 我们使用了费用提前计算思想。
  • 通过前缀和使得整个式子只包含与i,j有关的变量和常数,通过移项,使得式子简化成f[i]+s1[i]+A[i]*B[j]=f[j]+s2[j]的形式,直接省去了j的枚举,时间复杂度降到O(N)。

2、运输小猫

  • 通过每只小猫的游玩时间和位置信息,将其与饲养员出发时间建立联系,便与任务安排很像了。
  • 同样使用前缀和将所有变量转为只与i,j有关的变量,最终式子化简为标准形式,时间O(N)。

3、特别行动队、仓库建设、玩具装箱

  • 几乎没什么区别,将DP方程写出来之后,通过前缀和去化简变量,最终简化式子为标准形式即可。
从上面的这些题中可以看出,我们大量运用了前缀和,就是为了可以通过预处理将DP方程中的变量简化为只与i,j有关的量,以便将式子化为标准形式,$$所以斜率优化DP就是要去简化变量,转化式子,剩下的就可以斜率优化掉一层枚举了$$

4、但是前缀和并不万能,来看 “土地购买”

image

首先毫无头绪,没有像前几道题那样点明必须连续购买,而是想买多少卖多少,这朴素转移就很难,pu-tao↑。
但是为了比较好判断谁的l(长)比较大,先把他们按l sort一遍,得到一个a不严格递增的序列,由前几道题的做题经验想到应该取连续的一段,来证明一下:

反证 :

如果不应该取连续的一段,那么就是取不连续的,num[i]表示i在序列中的位置,设num[a]<num[b]<num[c],取a,c,不取b。
如果取c不取b,说明w[c](宽)<w[b],不然w[c]>w[b]&&l[c]>l[b]就必然会把b包括进来,接下来分类讨论一下:

  1. w[a]<=w[b]:
    image
    显然b可以包括进a,不行。
  2. w[a]>w[b]:
    image
    (1):w[a]是b所包括范围之内最大的w
    ①:w[a]是c所包括范围之内最大的w,因为l[b]<=l[c],所以a属于b更优。
    ②:w[a]不是c所包括范围之内最大的w,那就可以把c所包括的最大的w[x]的x给b,因为l[b]<=l[c].
    (2):w[a]不是b所包括范围之内最大的w,那么a不会对b的答案造成影响,给b更优。
    所以a应该跟b,即不连续的取一段不是最优解。
证毕

由上述证明过程引发出一个想法:$$ w[i]>w[j]\ and\ l[i]>l[j],j完全可以被i包含,j无用 $$,所以整个序列要去掉那些无用的元素,用以w为关键字单调递减队列跑一遍,即可得到最终序列,l递增,w递减:
image

由此可以写出DP方程:$$f[i]=f[j]+l[i]*w[j+1]$$,完美符合标准形式,切横坐标-w[j+1]具有单调性,直接跑单调队列即可。

pu-tao↑zher↑↓
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define laoda MAN
#define MAN What Can I Say?
typedef long long ll;
typedef pair<int,int> pii;
const ll linf=0x3f3f3f3f7fffffff;
inline int read(){char c=getchar();int x=0;bool f=1;while(c<'0'||c>'9')f=c=='-'?0:1,c=getchar();while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();return f==0?-x:x;
}
const int N=5e4+10,inf=0x7f7f7f7f;
ll n,f[N],q[N],l=1,r,m[N];
struct jj{ll a,b;//a->l,b->winline bool operator <(const jj &x)const{return a<x.a;}
}man[N];
int main(){#ifndef ONLINE_JUDGEfreopen("in.in","r",stdin);freopen("out.out","w",stdout);#endif	n=read();for(int i=1;i<=n;++i){man[i]={read(),read()};}sort(man+1,man+1+n);for(int i=1;i<=n;++i){while(l<=r&&man[q[r]].b<=man[i].b)--r;q[++r]=i;}for(int i=l;i<=r;++i)man[i-l+1]=man[q[i]];n=r-l+1;l=1,r=1;q[1]=0;for(int i=1;i<=n;++i){int j=q[l+1],k=q[l];while(l<r&&f[j]-f[k]<=man[i].a*(man[k+1].b-man[j+1].b))k=q[++l],j=q[l+1];f[i]=f[k]+man[i].a*man[k+1].b;j=q[r],k=q[r-1];while(l<r&&(f[j]-f[k])*(man[i+1].b-man[j+1].b)<=(f[i]-f[j])*(man[j+1].b-man[k+1].b))j=q[--r],k=q[r-1];q[++r]=i;}cout<<f[n];
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/42853.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

记一次编译GCC的经历

背景 因为有在Linux环境编译C++程序的需求,故我于近日在电脑上安装了WSL。鉴于APT(Ubuntu的包管理器)提供的GCC版本较老(确切来说,APT会根据Ubuntu版本来下载并安装某个版本的GCC,不一定为最新,例如对Ubuntu 22.04而言,从APT获取的最新版本GCC为11.2.0),我便尝试自己…

sql左连接查询时,右表的条件应该写在WHERE后面还是ON后面

在SQL的左连接查询(LEFT JOIN)中,右表的条件应尽量写在ON子句后面。这是因为:ON子句:用于定义两个表之间的连接条件,决定了哪些行会从右表中选择出来与左表进行匹配。 WHERE子句:用于过滤整个结果集,在连接操作完成之后应用。如果将针对右表的过滤条件放在WHERE子句而不…

使用 .NET 集成 MinIO 实现高效对象存储

引言https://min.io/在现代软件开发中,存储和管理大量的非结构化数据(如图片、视频和文档)变得越来越重要。对象存储解决方案如 Amazon S3 已成为主流,但其高昂的成本和对公有云的依赖使得很多开发者寻求开源和自托管的替代方案。MinIO 作为一款高性能的开源对象存储系统,…

R3CTF -Cry(部分)

上线看了一下题,就做了三个,还是太菜了(T~T) r0system 题目出的很抽象,就是代码长,没有啥别的考点,先创建一个账号,登录进入后修改Alice账号密码,再使用Alice登录拿到私钥就好了。 from hashlib import md5 from Crypto.Cipher import AES from Crypto.Util.number im…

后端接口性能优化分析

原文链接:https://blog.csdn.net/qq_40851232/article/details/134401234定位问题 1.慢查询日志 通常情况下,为了定位sql的性能瓶颈,我们需要开启mysql的慢查询日志。把超过指定时间的sql语句,单独记录下来,方面以后分析和定位问题。 开启慢查询日志需要重点关注三个参数:…

「笔记」递归算法复杂度分析

可恶的算法分析与设计!!!目录写在前面递归算法形式递归树大力求和主定理 Master Theorem典题1234写在最后 写在前面 可恶的算法分析与设计!!! 递归算法形式 对于一个输入规模为 \(n\) 的递归算法,每次均为将整个问题划分为 \(a\) 个规模为 \(\frac{n}{b}\) 的子问题,回…

NOIP2024模拟12:孤帆远影

这两次模拟赛都不是很专注!T1两次都G掉了!迅速调整状态,专注于自己的思考,打好草稿!NOIP2024模拟12:孤帆远影听了机房同学的讨论,于是T1死磕冒泡和逆序对做法。最后只得了40pts。 思想对了,但不是自己的做法。 还是要坚持自己想,坚持自己可以想出来,不要被任何人带偏。T1一…

mORMot and Open Source friends SynProject Tutorial (SynProject教程)

mORMot and Open Source friends SynProject Tutorial--(SynProject 教程) 第一步 本页介绍SynProject的一些典型用法。 我们将为mORMot框架本身创建一个源代码存储库和相关的文档。 您要求文档,我们将通过SynProject自动生成它! 我们需要什么 因此,我们在硬盘上的D:\Dev\Li…