博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【笔记篇】斜率优化dp(四) ZJOI2007仓库建设
阅读量:5360 次
发布时间:2019-06-15

本文共 1412 字,大约阅读时间需要 4 分钟。

传送门

\(n\leq1e6\), 显然还是\(O(n)\)的做法.

这个题有个条件是只能运往编号更大的工厂的仓库, 这也是写出朴素dp的方程的条件.
我们令\(f[i]\)表示前\(i\)个工厂的最小花费, 那么易得
\[f[i]=min\{f[j]+t(j,i)\}\]
其中这个\(t(j,i)\)表示将\((j,i)\)这个区间的东西运到\(i\)的总费用. 很显然, 这个式子要\(O(1)\)求出来才行, 不然复杂度就要炸...
那么怎么\(O(1)\)求呢?
考虑类似于前缀和的性质.
这里写图片描述
我们令\(s_i\)为将\((1,i]\)这个区间中所有工厂的产品运到\(i\)的总花费, \(c_i\)表示前\(i\)个工厂的产品总量, \(d_i\)表示第\(i\)个工厂的坐标, 我们发现, 如果对\(i,j\)做一波前缀和相减, 那么前\(j\)个点的货物都被多运了\(d_i-d_j\)的距离... 所以就可以推出
\[t(j,i)=s_i-s_j-c_j*(d_i-d_j)\]
这样就可以扔进状态转移方程进行斜率优化了... 化完之后的式子是:
\(f[j]-s[j]+c[j]*d[j]\)=\(d[i]\)\(c[j]\)+\(f[i]-s[i]-w[i]\)
然后求的是最小值, 斜率还递增(这好像是最常见的一种了吧?), 那就跟之前一样咯= =
然而还是把演草纸上\(d[i],c[j]\)的数组名抄反了WA了一次 但为什么可以过样例啊QAQ
然后就是没有压行的代码: (简单的斜率优化似乎总可以写成标准的20行?

#include 
const int N=1e6+6;typedef long long LL;LL f[N],s[N],c[N];int q[N],w[N],d[N],n,h,t;inline int gn(int a=0,char c=0){ for(;c<'0'||c>'9';c=getchar()); for(;c>47&&c<58;c=getchar())a=a*10+c-48;return a;}double slope(int x,int y){ return 1.0*(f[x]-s[x]+c[x]*d[x]-f[y]+s[y]-c[y]*d[y])/(c[x]-c[y]);}int main(){ n=gn(); for(int i=1;i<=n;++i){ d[i]=gn();c[i]=c[i-1]+gn();w[i]=gn(); s[i]=s[i-1]+c[i-1]*(d[i]-d[i-1]); } for(int i=1,j;i<=n;++i){ while(h
<=d[i]) ++h; j=q[h]; f[i]=f[j]+s[i]-s[j]-c[j]*(d[i]-d[j])+w[i]; while(h
=slope(q[t],i)) --t; q[++t]=i; } printf("%lld\n",f[n]);}

转载于:https://www.cnblogs.com/enzymii/p/8413698.html

你可能感兴趣的文章
关于标签之间因为换行等问题造成的空白间距问题处理
查看>>
hdu 2767(tarjan)
查看>>
sklearn之分类模型混淆矩阵和分类报告
查看>>
MySQL各存储引擎
查看>>
项目--简单导出CSV文件
查看>>
Oracle session相关数据字典(一)
查看>>
织梦文章内容提取第一张或者多张图片输出
查看>>
C#用正则表达式 获取网页源代码标签的属性或值
查看>>
BZOJ 3399 [Usaco2009 Mar]Sand Castle城堡(贪心)
查看>>
WCF(一) 简单的认知
查看>>
[MFC][DShow]简单例子
查看>>
Luogu P1141 01迷宫【搜索/dfs】By cellur925
查看>>
js onclick事件传参
查看>>
WiCloud 商业Wi-Fi管理平台
查看>>
团队项目--未完待续
查看>>
双重标准,我该怎么解决
查看>>
python中的网页标签等字符处理
查看>>
Mybatis输入类型和结果类型
查看>>
Linux常用命令(五)
查看>>
Linux常用命令(四)
查看>>