斜率优化解题报告(uoj转)

news/2024/9/27 9:09:21

任务安排1~3:

模版。用到一个著名的思想:费用提前计算

暴力维数高的原因是不能较快的知道前面分了几批

但是一旦分了一批,对后面都会有\(S\)的时间叠加

所以不妨设\(f_i\)表示已知会花费的时间min,

\(f_i = \min_{j=1}^{i-1} f_j + (SC_i-SC_j) \cdot ST_i + S \cdot (SC_n-SC_j)\)

\(O(n^2)\)通过T1.

大力拆式子,发现有一个叫做\(ST_i \cdot SC_j\)的玩意,i,j之间无法独立

不慌,还是先移项,得

\(f_j-SC_j \cdot S = ST_i \cdot SC_j + f_i - ST_i \cdot SC_i - S \cdot SC_n\)

\(i\)为常数,\(j\)为变量的话此为一次函数,维护下凸包即可

关于为何是下凸包:

1.直观理解:下面的截距才小,\(f_i\)才小

2.线性规划的结论证明

3.分类讨论证明

能理解就行

这样2、3都秒了,只是在单调队列中取哪个做答案的问题

其实还可以有4,\(T_i\)也能是负数

在凸包中间插点,set维护即可


B. Cats Transport

乍一看很难搞,两三个属性

分析一波,若feeder(\(t\)时刻出发)接到了一只cute cat,则它应该等待\(t+SD_i-T_i\)分钟(\(t \geq T_i -SD_i\)

所以可设\(a_i = T_i - SD_i\)并排序

不难发现\(a\)小的cat应由出发早的人接

人少,可设\(f_{i,j}\)表示前\(i\)个人接走前\(j\)个cat最小时间

\(f_{i,j}=f_{i-1,k}+(j-k)*Sa_j-(Sa_j-Sa_k)\)

(贪心设置的t,无需多言)

\(i\)直接滚掉,移项得

\(pre_j + Sa_j = j \cdot Sa_i + f_i + (i-1) \cdot Sa_i\)

结束战斗


P3195 [HNOI2008]玩具装箱

套路了。。。

\(f_i\)表示前\(i\)个分好最小代价

\(s_i = \sum_{j=1}^i c_j\)

\(f_i = f_j + (s_i-s_j+i-j-1-L)^2\)

\(a_i=s_i+i\) , \(R = 1 - L\) , 则

\(f_i = f_j + (a_i - a_j + R)^2\),

化简即可不想写了

#include<bits/stdc++.h>
using namespace std;
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define N 100005
#define ll long long
int n,q[N],hh,tt;
ll f[N],s[N],D;
ll get_y(int j){return f[j]+(s[j]-D)*(s[j]-D);
}
int main(){scanf("%d%lld",&n,&D);D=-1ll-D;fr(i,1,n){scanf("%lld",&s[i]);s[i]+=s[i-1]; }fr(i,1,n)s[i]+=1ll*i;fr(i,1,n){while(hh<tt&&(get_y(q[hh+1])-get_y(q[hh]))<2ll*s[i]*(s[q[hh+1]]-s[q[hh]]))hh++;f[i]=f[q[hh]]+1ll*(s[i]-s[q[hh]]+D)*(s[i]-s[q[hh]]+D); while(hh<tt&&(get_y(q[tt])-get_y(q[tt-1]))*(s[i]-s[q[tt]])>=(get_y(i)-get_y(q[tt]))*(s[q[tt]]-s[q[tt-1]]))tt--;q[++tt]=i;}printf("%lld\n",f[n]);return 0;
}

P2120 [ZJOI2007]仓库建设

\(f_i\)表示前\(i\)个的min

\(f_i = \min_{j=1}^{i-1} (f_j + c_i + x_i \cdot (Sp_i - Sp_j) - (Sxp_i - Sxp_j))\)

tips:其实不需要把整个式子拆开,只需观察出\(x\),\(y\),\(Slope\)即可

还是很好找的

注意此时钦定了\(n\)号位必建仓库,特判即可

#include<bits/stdc++.h>
using namespace std;
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define N 1000005
#define ll __int128
int n,q[N],hh,tt;
ll f[N],x[N],c[N],Sp[N],Sxp[N];
ll get_y(int j){return f[j]+Sxp[j];
}
int main(){scanf("%d",&n);int tmp,tmp1,tmp2,fl=0;fr(i,1,n){scanf("%d%d%d",&tmp1,&tmp,&tmp2);x[i]=tmp1,c[i]=tmp2;Sp[i]=Sp[i-1]+tmp;Sxp[i]=Sxp[i-1]+x[i]*tmp;if(i==n&&tmp==0)fl=1;}fr(i,1,n){while(hh<tt&&(get_y(q[hh+1])-get_y(q[hh]))<(Sp[q[hh+1]]-Sp[q[hh]])*x[i])hh++;f[i]=f[q[hh]]+c[i]+x[i]*(Sp[i]-Sp[q[hh]])-(Sxp[i]-Sxp[q[hh]]);while(hh<tt&&(get_y(q[tt])-get_y(q[tt-1]))*(Sp[i]-Sp[q[tt]])>=(get_y(i)-get_y(q[tt]))*(Sp[q[tt]]-Sp[q[tt-1]]))tt--;q[++tt]=i;}printf("%lld\n",(long long)f[n]-fl*c[n]);return 0;
}

P3628 [APIO2010]特别行动队

一时竟分不清哪个是模版

\(f_i = f_j + A(s_i - s_j)^2+B(s_i-s_j) + C\)

《不难看出》,
\(y = f_j + As_j^2-Bs_j\) ,
\(x = s_j\) , \(Slope = 2As_i\)

舒服~

#include<bits/stdc++.h>
using namespace std;
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define N 1000005
#define ll long long
int n,q[N],hh,tt;
ll s[N],f[N],A,B,C;
ll get_y(int j){return f[j]+A*s[j]*s[j]-B*s[j];
}
int main(){scanf("%d%lld%lld%lld",&n,&A,&B,&C);ll x;fr(i,1,n){scanf("%lld",&x);s[i]=s[i-1]+x;}fr(i,1,n){while(hh<tt&&get_y(q[hh+1])-get_y(q[hh])>(s[q[hh+1]]-s[q[hh]])*2ll*A*s[i])hh++;int j=q[hh];f[i]=f[j]+A*(s[i]-s[j])*(s[i]-s[j])+B*(s[i]-s[j])+C;while(hh<tt&&(get_y(q[tt])-get_y(q[tt-1]))*(s[i]-s[q[tt]])<=(get_y(i)-get_y(q[tt]))*(s[q[tt]]-s[q[tt-1]]))tt--;q[++tt]=i;}printf("%lld\n",f[n]);return 0;
}

P4360 [CEOI2004]锯木厂选址

可以看出考虑\(f_i\)表示\(i\)处已经有一个兜底,还能再建一个,运完前\(i\)个最小代价

\(f_i\)

\(= \min_{j=1}^{i-1}(\sum_{k=1}^j(x_j-x_k) \cdot p_k+\sum_{k=j+1}^i(x_i-x_k) \cdot p_k)\)

\(= x_j\sum_{k=1}^j p_k+x_i\sum_{k=j+1}^i p_k -\sum_{k=1}^i x_k \cdot p_k\)

\(= x_j \cdot Sp_j + x_i \cdot Sp_i - x_i \cdot Sp_j - Sxp_i\)

整理得

\(x_j \cdot Sp_j = x_i \cdot Sp_j + f_i - x_i \cdot Sp_i + Sxp_i\)

没有\(f_j\)好害怕

一样嘛,就是把只有\(j\)的全移到左边当\(y\)\(ij\)乘积项当\(x\),其余截距,这是精髓

求出\(f_i\)\(ans = \min_{i=1}^n (f_i + \sum_{j=i+1}^n(x_{n+1}-x_j) \cdot p_j)\)

小发现:\(\sum x \cdot p\)可以最后一起算

#include<bits/stdc++.h>
using namespace std;
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define N 20005
#define ll long long
int n,q[N],hh,tt;
ll ans=1e18,f[N],x[N],p[N],res;
ll get_y(int j){return x[j]*p[j];
}
int main(){scanf("%d",&n);ll tmp;fr(i,1,n){scanf("%lld%lld",&p[i],&tmp);res+=x[i]*p[i];p[i]+=p[i-1];x[i+1]=x[i]+tmp;}fr(i,1,n){while(hh<tt&&get_y(q[hh+1])-get_y(q[hh])<(p[q[hh+1]]-p[q[hh]])*x[i])hh++;f[i]=x[i]*p[i]+p[q[hh]]*(x[q[hh]]-x[i]);while(hh<tt&&(get_y(q[tt])-get_y(q[tt-1]))*(p[i]-p[q[tt]])>(get_y(i)-get_y(q[tt]))*(p[q[tt]]-p[q[tt-1]]))tt--;q[++tt]=i;ans=min(ans,f[i]+x[n+1]*(p[n]-p[i]));}printf("%lld\n",ans-res);return 0;
}

完结撒电脑

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

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

相关文章

救园倒计时:救园最后4天

救园目的:园子这三年困难阶段靠贷款维持,救园是为了还掉贷款,度过难关。救园方式: 终身会员计划,会员,捐助,周边。救园之后,一边增加收入来源,一边加快推进园子的商业化救园进展 截止9月27日 08:55终身会员:终身VIP会员名额还剩37个,终身VIP会员名额还剩130个 会员总…

将对象的属性为数值型的转换为String

将对象的属性为数值型的转换为String 1、新建一个类 //注意:此处为待转换的类型,return true 不好用,必须将待转换的类型一一列出using Newtonsoft.Json;namespace WinFormsApp1.Common {public class ToStringConverter : JsonConverter{public override bool CanConvert(T…

《HelloGitHub》第 102 期

兴趣是最好的老师,HelloGitHub 让你对编程感兴趣!简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。github.com/521xueweihan/HelloGitHub这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 Python、Java、Go、C/C++、Swift...让你在短…

弹幕树洞项目功能新增篇

项目地址 项目后端地址:https://github.com/ZyPLJ/ZYTteeHole项目前端页面地址:ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue目前项目测试访问地址:http://tree.pljzy.top/ 注意是http,输成https就访问到博客里面去了。系列文章📖.NET Core搭配V…

Cisco Secure Firewall Threat Defense 7.6.0 发布下载,新增功能概览

Cisco Secure Firewall Threat Defense 7.6.0 发布下载,新增功能概览Cisco Secure Firewall Threat Defense 7.6.0 发布下载,新增功能概览 Firepower Threat Defense (FTD) Software Release 7.6.0 Firepower 1100/3100/4100/4200/9300 Security Appliance 请访问原文链接:h…

【译】通过新的 WinUI 工作负荷和模板改进,深入原生 Windows 开发

我们创建了一个新的 Windows Dev Center 页面,简化了我们的 Getting Started with WinUI 文档,并与 Visual Studio 合作来改善开发人员在工作负荷和模板方面的体验。在 Build 2024 上,WinUI 团队宣布将重新关注 WinUI,将其作为我们推荐的原生 Windows 应用开发的首要应用开…

Windows10永久拒绝升级Win11

一、使用组策略阻止升级到windows11 需要专业版或企业版的Windows 10才能访问组策略编辑器。以下是操作步骤:单击开始菜单,输入gpedit.msc,打开本地组策略编辑器。 导航到“计算机配置”>“管理模板”>“Windows组件”>“Windows更新”>“适用于企业的Windows更…

arcgis怎样把面图层按另一面图层分割

摘自https://jingyan.baidu.com/article/6079ad0e9b5c8428fe86db70.htmlarcgis的桌面软件 主要应用于空间数据处理和管理,工作中往往会遇到要批量分割大量的面状数据,并且要按照其所处面的关系赋值。1、打开ArcMap软件,把两个面图层都加载到视图区域内,如下图2、在工具栏中…