链接:

P2120


题意:

有 \(n\) 个点依次编号为 \(1\sim n\)。给出这 \(n\) 个点的信息,包括位置 \(x_i\),所拥有的的物品数量 \(p_i\),在此建设一个仓库的费用 \(c_i\)。

每个物品可以向编号更大的点移动,一个物品移动一个单位距离的费用为1。

求将所有物品都放进仓库所需的最小费用。


分析:

我们可以比较容易地想出一个 \(dp[i]\) 表示在第 \(i\) 个点建一个仓库时的最优费用,那么枚举上一个仓库的位置,有

\[dp[i]=dp[j]+\sum_{k=j+1}^i(x_i-x_k)\cdot p_k+c_i
\]

把 \(\sum\) 拆开,有

\[dp[i]=dp[j]+x_i\sum_{k=j+1}^ip_k-\sum_{k=j+1}^i(x_k\cdot p_k)+c_i
\]

于是设 \(sum1[i]=\sum\limits_{k=1}^ip_k\),\(sum2[i]=\sum\limits_{k=1}^i(x_k\cdot p_k)\),可以预处理出来。

\[dp[i]=dp[j]+x_isum1[i]-x_isum1[j]-sum2[i]+sum2[j]+c_i
\]

发现有 \(x_isum1[j]\) 这种既与当前位置有关,又与决策有关的项,于是按照斜率优化的套路,我们把式子化成直线表达式的形式:

\[(sum2[j]+dp[j])=x_isum1[j]+(dp[i]-x_isum1[i]+sum2[i]-c_i)
\]

于是我们只需要最小化斜率为 \(x_i\),过点 \((sum1[j],sum2[j]+dp[j])\) 的直线的截距。

发现和玩具装箱那题很像,也是维护一个下凸包,同样有斜率 \(x_i\) 递增,同样用单调队列优化,于是就可以 \(O(n)\) 了。


算法:

单调队列维护下凸包,同时维护最优决策点,然后每次根据最优决策的信息得到 \(dp[i]\),继续维护凸包即可。时间复杂度 \(O(n)\)。

细节1:

这个细节是仅关于本题的,也是洛谷上的 hack 数据。

我们对 dp 的定义是在第 \(i\) 个位置建一个仓库时的最优费用,于是如果 dp 完直接输出 dp[n] 是有问题的。当最后连续多个点根本没有物品时,最后一个仓库可能会建在最后一个有物品的点和最后一个点及其之间的所有点上,所以我们最后还要取一个 min

细节2:

另外,对于决策点横坐标相等的问题,由于本题数据弱放了过去,所以我会在 [SDOI2012]任务安排 的题解中详细说明这个问题。


代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define in read()
inline int read(){
int p=0,f=1;
char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){p=p*10+c-'0';c=getchar();}
return p*f;
}
#define X(x) (sum1[x])
#define Y(x) (sum2[x]+dp[x])
#define dx(x,y) (X(x)-X(y))
#define dy(x,y) (Y(x)-Y(y))
#define slope(x,y) (dx(x,y)?(double)dy(x,y)/dx(x,y):dy(x,y)>=0?inf:-inf)
const int N=1e6+5;
const int inf=0x7fffffffffffffff;
int n,x[N],p[N],c[N],dp[N],sum1[N],sum2[N],q[N],qh,qt;
signed main(){
n=in;
for(int i=1;i<=n;i++)
x[i]=in,p[i]=in,c[i]=in,
sum1[i]=sum1[i-1]+p[i],
sum2[i]=sum2[i-1]+x[i]*p[i];
qh=qt=1;
for(int i=1;i<=n;i++){
while(qh<qt&&slope(q[qh+1],q[qh])<x[i])qh++;
dp[i]=Y(q[qh])-x[i]*X(q[qh])+x[i]*sum1[i]-sum2[i]+c[i];
if(X(i)==X(q[qt])&&qh<qt){if(Y(i)<Y(q[qt]))qt--;else continue;}
while(qh<qt&&slope(q[qt],q[qt-1])>slope(i,q[qt-1]))qt--;
q[++qt]=i;
}
int ans=dp[n];
while(!p[n])ans=min(ans,dp[--n]);
cout<<ans;
return 0;
}

洛谷 P2120 [ZJOI2007] 仓库建设的更多相关文章

  1. 洛谷P2120 [ZJOI2007]仓库建设 斜率优化DP

    做的第一道斜率优化\(DP\)QwQ 原题链接1/原题链接2 首先考虑\(O(n^2)\)的做法:设\(f[i]\)表示在\(i\)处建仓库的最小费用,则有转移方程: \(f[i]=min\{f[j] ...

  2. 洛谷2120 [ZJOI2007]仓库建设(斜率优化dp)

    感觉和锯木厂那个题很类似的. 其实这个题还那个题唯一的区别就是\(dp\)转移式子中的\(f\)变成了\(g\) qwq不想多说了 直接看我的前一篇题解吧qwq #include<iostrea ...

  3. P2120 [ZJOI2007]仓库建设

    P2120 [ZJOI2007]仓库建设 怎么说呢?算是很水的题了吧... 只要不要一开始就把dp想错就行... #include<bits/stdc++.h> #define ll lo ...

  4. P2120 [ZJOI2007]仓库建设 斜率优化dp

    好题,这题是我理解的第一道斜率优化dp,自然要写一发题解.首先我们要写出普通的表达式,然后先用前缀和优化.然后呢?我们观察发现,x[i]是递增,而我们发现的斜率也是需要是递增的,然后就维护一个单调递增 ...

  5. P2120 [ZJOI2007] 仓库建设(斜率优化DP)

    题意:\(1\sim N\) 号工厂,第\(i\) 个工厂有\(P_i\)个成品,第\(i\)个工厂建立仓库需要\(C_i\)的费用,该工厂距离第一个工厂的距离为\(X_i\),编号小的工厂只能往编号 ...

  6. P2120 [ZJOI2007]仓库建设(dp+斜率优化)

    思路 首先暴力DP显然,可以得20分 加上一个前缀和优化,可以得到40分 然后上斜率优化 设\(sum_i\)为\(\sum_{1}^iP_i\),\(sump_i\)为\(\sum_{1}^{i}P ...

  7. 【洛谷】2120:[ZJOI2007]仓库建设【斜率优化DP】

    P2120 [ZJOI2007]仓库建设 题目背景 小B的班级数学学到多项式乘法了,于是小B给大家出了个问题:用编程序来解决多项式乘法的问题. 题目描述 L公司有N个工厂,由高到底分布在一座山上. 工 ...

  8. bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)

    题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...

  9. BZOJ 1096: [ZJOI2007]仓库建设 [斜率优化DP]

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4201  Solved: 1851[Submit][Stat ...

随机推荐

  1. LVS负载均衡集群--NAT模式部署

    目录: 一.企业群集应用概述 二.负载均衡群集架构 三.负载均衡群集工作模式分析 四.关于LVS虚拟服务器 五.NAT模式 LVS负载均衡群集部署 一.企业群集应用概述 1.群集的含义 Cluster ...

  2. XXE从0到1

    XXE从0到1 1. XXE概述 XXE(XML External Entity Injection)即XML外部实体注入.漏洞是在对不安全的外部实体数据进行处理时引发的安全问题. 下面我们主要介绍P ...

  3. [Linux系列]DNS系列理论笔记与DNS服务器配置

    0x01 基础术语 DNS(Domain Name System,域名系统),域名和IP地址相互映射的一个分布式数据库,简而言之就是通过更易记忆的域名代替IP去访问一个网站. FQDN(Fully Q ...

  4. 关于pycharm创建django1.x和3.x项目的说明

    1.我创建了两个模板文件分别代表django1.x和3.x 2.两个模板文件分别为Django1Template和Django3Template (不同模板文件中存放不同的django版本) 3.使用 ...

  5. symfony中模板生成路径两种方式

    1. 使用url('route_a_b_c')  这种方式会是全路径 : http://www.test.com/a/b/c 2. 使用path('route_a_b_c') 这种方式只是路径: /a ...

  6. jquery获取一个元素符合条件的第一个父元素

    closest jQuery 1.3新增.从元素本身开始,逐级向上级元素匹配,并返回最先匹配的元素.. closest会首先检查当前元素是否匹配,如果匹配则直接返回元素本身.如果不匹配则向上查找父元素 ...

  7. JDK1.8源码(四)——java.util.Arrays类

    一.概述 1.介绍 Arrays 类是 JDK1.2 提供的一个工具类,提供处理数组的各种方法,基本上都是静态方法,能直接通过类名Arrays调用. 二.类源码 1.asList()方法 将一个泛型数 ...

  8. P4351-[CERC2015]Frightful Formula【组合数学,MTT】

    正题 题目链接:https://www.luogu.com.cn/problem/P4351 题目大意 \(n*n\)的矩形,给出第一行和第一列的数,剩下的满足\(F_{i,j}=a*F_{i,j-1 ...

  9. P4357-[CQOI2016]K远点对【K-Dtree】

    正题 题目链接:https://www.luogu.com.cn/problem/P4357 题目大意 平面上给出\(n\)个点,求第\(k\)远的点对距离. 解题思路 \(\text{K-Dtree ...

  10. WPF进阶技巧和实战07--自定义元素02

    在01节中,研究了如何开发自定义控件,下节开始考虑更特殊的选择:派生自定义面板以及构建自定义绘图 创建自定义面板 创建自定义面板是一种比较常见的自定义控件开发子集,面板可以驻留一个或多个子元素,并且实 ...