[ZJOI2007]仓库建设(斜率优化)
L公司有N个工厂,由高到底分布在一座山上。
工厂1在山顶,工厂N在山脚。 由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用。
突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏。
由于地形的不同,在不同工厂建立仓库的费用可能是不同的。第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库的费用是Ci。
对于没有建立仓库的工厂,其产品应被运往其他的仓库进行储藏,而由于L公司产品的对外销售处设置在山脚的工厂N,故产品只能往山下运(即只能运往编号更大的工厂的仓库),当然运送产品也是需要费用的,假设一件产品运送1个单位距离的费用是1。
假设建立的仓库容量都都是足够大的,可以容下所有的产品。你将得到以下数据:
- 工厂i距离工厂1的距离Xi(其中X1=0);
- 工厂i目前已有成品数量Pi;
- 在工厂i建立仓库的费用Ci;
请你帮助L公司寻找一个仓库建设的方案,使得总的费用(建造费用+运输费用)最小。
Solution
有一个非常好的东西,就是只能运送到到比自身编号大的点,这样我们就可以列出dp方程。
dp[i]=max(dp[j]+x[i]*(sum[i]-sum[j])+sump[i]-sump[j]+c[i])
这里sum[i]指p[i]的前缀和,sump[i]指x[i]*p[i]的前缀和。
这样是n^2的,考虑如何优化。
按照惯例,我们把含i的式子和含j的式子分开来看。
dp[i]=dp[j]+x[i]*sum[i]-x[i]*sum[j]+sump[i]-sump[j]+c[i];
令a[i]=x[i]*sum[i]-sump[i]-dp[i] . b[i]=dp[i]+sump[i];
dp式子就变成了x[i]*sum[j]-a[i]=b[i]
为了求最小值,我们就维护一个下凸包。
观察到x[i]和sum[i]都是单调递增的,用单调队列就可以了。
Code
#include<iostream>
#include<cstdio>
#define Y(i) (dp[i]+sup[i])
#define X(i) (sum[i])
#define N 1000002
using namespace std;
long long x[N],y[N],p[N],c[N],sum[N],dp[N],sup[N],n,h,t,q[N];
inline int rd(){
int x=;char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c)){
x=(x<<)+(x<<)+(c^);
c=getchar();
}
return x;
}
inline double calc(int i,int j){
return 1.0*((double)Y(j)-Y(i))/(double)(X(j)-X(i));
}
int main(){
n=rd();
for(int i=;i<=n;++i)x[i]=rd(),p[i]=rd(),c[i]=rd(),sum[i]=sum[i-]+p[i],sup[i]=sup[i-]+p[i]*x[i];
for(int i=;i<=n;++i){
while(h<t&&calc(q[h],q[h+])<x[i])h++;
dp[i]=dp[q[h]]+x[i]*(sum[i]-sum[q[h]])-sup[i]+sup[q[h]]+c[i];
while(h<t&&calc(q[t-],q[t])>calc(q[t],i))t--;
q[++t]=i;
}
cout<<dp[n];
return ;
}
[ZJOI2007]仓库建设(斜率优化)的更多相关文章
- bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)
题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...
- BZOJ 1096: [ZJOI2007]仓库建设 [斜率优化DP]
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4201 Solved: 1851[Submit][Stat ...
- 【BZOJ1096】[ZJOI2007]仓库建设 斜率优化
[BZOJ1096][ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司 ...
- bzoj1096[ZJOI2007]仓库建设 斜率优化dp
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5482 Solved: 2448[Submit][Stat ...
- 【bzoj1096】[ZJOI2007]仓库建设 斜率优化dp
题目描述 L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L ...
- P2120 [ZJOI2007]仓库建设 斜率优化dp
好题,这题是我理解的第一道斜率优化dp,自然要写一发题解.首先我们要写出普通的表达式,然后先用前缀和优化.然后呢?我们观察发现,x[i]是递增,而我们发现的斜率也是需要是递增的,然后就维护一个单调递增 ...
- [BZOJ1096] [ZJOI2007] 仓库建设 (斜率优化)
Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天, ...
- 洛谷P2120 [ZJOI2007]仓库建设 斜率优化DP
做的第一道斜率优化\(DP\)QwQ 原题链接1/原题链接2 首先考虑\(O(n^2)\)的做法:设\(f[i]\)表示在\(i\)处建仓库的最小费用,则有转移方程: \(f[i]=min\{f[j] ...
- [ZJOI2007] 仓库建设 - 斜率优化dp
大脑真是个很优秀的器官,做事情之前总会想着这太难,真的逼着自己做下去,回头看看,其实也不过如此 很朴素的斜率优化dp了 首先要读懂题目(我的理解能力好BUG啊) 然后设\(dp[i]\)表示处理完前\ ...
随机推荐
- 在Linux添加PYTHONPATH方法以及修改环境变量方法
Linux下设置环境变量有三种方法,一种用于当前终端,一种用于当前用户,一种用于所有用户: 一:用于当前终端: 在当前终端中输入: export PATH=$PATH:<你的要加入的路径> ...
- java中的定时任务小示例
package package_1; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; ...
- C#复习笔记(5)--C#5:简化的异步编程(异步编程的基础知识)
异步编程的基础知识 C#5推出的async和await关键字使异步编程从表面上来说变得简单了许多,我们只需要了解不多的知识就可以编写出有效的异步代码. 在介绍async和await之前,先介绍一些基础 ...
- Java Hash集合的equals()与hashCode() 方法
Java 集合实现类,无论是HashSet.HashMap等所有的Hash算法实现的集合类(后面简称Hash集合),加入的对象必须实现 hashCode() 与 equals() 方法,稍微不同的地方 ...
- Sqlserver tablediff的简单使用
1. 先列举一下自己简单的比较语句 tablediff -sourceserver 10.24.160.73 -sourcedatabase cwbasemi70 -sourceschema lcmi ...
- sqlserver常用语法
--临时表 IF OBJECT_ID('tempdb..#Entry') is not null BEGIN DROP TABLE #Entry END ------------------- ...
- Appscanner实验还原code2
import _pickle as pickle from sklearn import svm, ensemble import random from sklearn.metrics import ...
- hive聚合函数和表生成函数
explode生成单独的一行
- java 中 Math类
package cn.liuliu.com; import java.math.BigDecimal; import java.math.BigInteger; /* * 一.Math类? * * 1 ...
- bzoj-1191(二分图最大匹配)
解题思路:比较裸的一道题,直接跑匈牙利就行了,但是要注意一点,这个兔崽子是在闯关,一道题回答不出来就没了,直接在题目循环那里加一个else break;就行了!!!; #include<iost ...