bzoj 1096 仓库建设 -斜率优化
L公司有N个工厂,由高到底分布在一座山上。如图所示,工厂1在山顶,工厂N在山脚。由于这座山处于高原内
陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用。突然有一天,L公司的总裁L先生接到气象
部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏。由于
地形的不同,在不同工厂建立仓库的费用可能是不同的。第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库
的费用是Ci。对于没有建立仓库的工厂,其产品应被运往其他的仓库进行储藏,而由于L公司产品的对外销售处设
置在山脚的工厂N,故产品只能往山下运(即只能运往编号更大的工厂的仓库),当然运送产品也是需要费用的,
假设一件产品运送1个单位距离的费用是1。假设建立的仓库容量都都是足够大的,可以容下所有的产品。你将得到
以下数据:1:工厂i距离工厂1的距离Xi(其中X1=0);2:工厂i目前已有成品数量Pi;:3:在工厂i建立仓库的费用
Ci;请你帮助L公司寻找一个仓库建设的方案,使得总的费用(建造费用+运输费用)最小。
Input
第一行包含一个整数N,表示工厂的个数。接下来N行每行包含两个整数Xi, Pi, Ci, 意义如题中所述。
Output
仅包含一个整数,为可以找到最优方案的费用。
Sample Input
3
0 5 10
5 3 100
9 6 10
Sample Output
32
Hint
在工厂1和工厂3建立仓库,建立费用为10+10=20,运输费用为(9-5)*3 = 12,总费用32。如果仅在工厂3建立仓库,建立费用为10,运输费用为(9-0)*5+(9-5)*3=57,总费用67,不如前者优。
【数据规模】
对于100%的数据, N ≤1000000。 所有的Xi, Pi, Ci均在32位带符号整数以内,保证中间计算结果不超过64位带符号整数。
题不是很难,dp方程推错了两次(每次都是从n往前),于是无限WA...第三次终于推对了。。(说完一堆废话赶快写正解)
朴素dp的方程(公式编辑器坏了,只能用画图了,请谅解)
$f\left [ i \right ] = \min\left \{ f\left [ j \right ] + \sum_{k = j + 1}^{i - 1}\left ( x_{i} - x_{k} \right )p_{k} \right \} + c_{i}$
一看是三维,死得没有悬念,只能想办法优化。Sigma一在更不好优化,只能先展开

发现P的求和和xP的求和都是可以用前缀和搞定的,于是设,sump[i] = P1 + P2 + ... + Pi,sumxp[i] = x1P1 + x2P2 + ... + xiPi
于是方程变成 f[i] = min{f[j] + xi(sump[i - 1] - sump[j]) - sumxp[i - 1] + sump[j]} + Ci
现在假设能转移到状态i的有两个状态j, k(j < k),如果j比k优,那么
f[j] + xi(sump[i - 1] - sump[j]) - sumxp[i - 1] + sump[j] < f[k] + xi(sump[i - 1] - sump[k]) - sumxp[i - 1] + sump[k]
拆括号化简
f[j] - xisump[j] + sump[j] < f[k] - xisump[k] + sump[k]
右边保留和i有关的单项式
(f[j] + sump[j]) - (f[k] + sump[k]) < xi(sump[j] - sump[k])
移项(还是注意不等号的方向)

于是又愉快地得到了斜率方程,对于状态i,(f[i] + sump[i])作为纵坐标,sump[i]作为横坐标,删掉上凸点,维护一条斜率递增的折线。
Code
/**
* bzoj
* Problem#1096
* Accepted
* Time:2312ms
* Memory:36464k
*/
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
typedef bool boolean;
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-');
if(x == '-'){
aFlag = -;
x = getchar();
}
for(u = x - ''; isdigit((x = getchar())); u = u * + x - '');
ungetc(x, stdin);
u *= aFlag;
} template<typename T>
class IndexedDeque{
public:
T* list;
int pfront;
int prear;
IndexedDeque():list(NULL), pfront(), prear(){ }
IndexedDeque(int size):pfront(), prear(){
list = new T[size];
}
void push_front(T x){ list[--pfront] = x; }
void push_back(T x) { list[prear++] = x; }
void pop_front() { ++pfront; }
void pop_back() { --prear; }
T front() { return list[pfront]; }
T rear() { return list[prear - ]; }
T& operator [](int pos){ return list[pfront + pos]; }
int size() { return prear - pfront; }
}; template<typename T>
inline void aalloc(T*& array, int size){ array = new T[(const int)(size + )]; } int n;
long long* sump;
long long* sumxp;
int* c;
int* x;
long long* f;
IndexedDeque<int> que; long long y_pos(int i) { return f[i] + sumxp[i]; }
double slope(int j, int k) { return (y_pos(j) - y_pos(k)) * 1.0 / (sump[j] - sump[k]); }
double cmpSlope(int i, int j, int k) { return slope(j, k) - x[i]; } inline void init() {
readInteger(n);
aalloc(sump, n);
aalloc(sumxp, n);
aalloc(c, n);
aalloc(x, n);
aalloc(f, n + );
sump[] = sumxp[] = x[] = ;
for(int i = , p; i <= n; i++){
readInteger(x[i]);
readInteger(p);
readInteger(c[i]);
sump[i] = sump[i - ] + p;
sumxp[i] = sumxp[i - ] + x[i] * 1LL * p;
}
} inline void solve() {
que = IndexedDeque<int>(n + );
f[] = ;
que.push_back();
for(int i = ; i <= n; i++) {
while(que.size() > && cmpSlope(i, que[], que[]) < ) que.pop_front();
int j = que.front();
f[i] = f[j] + x[i] * (sump[i - ] - sump[j]) - sumxp[i - ] + sumxp[j] + c[i];
while(que.size() > && slope(que[que.size() - ], que[que.size() - ]) >= slope(que[que.size() - ], i)) que.pop_back();
que.push_back(i);
}
printf(AUTO"\n", f[n]);
} int main() {
init();
solve();
return ;
}
bzoj 1096 仓库建设 -斜率优化的更多相关文章
- bzoj 1096 仓库建设 —— 斜率优化DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1096 设 f[i] 为 i 作为最后一个仓库时前 i 个工厂的答案,最后的答案当然是 f[n ...
- BZOJ 1096: [ZJOI2007]仓库建设 [斜率优化DP]
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4201 Solved: 1851[Submit][Stat ...
- bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)
题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...
- 【BZOJ-1096】仓库建设 斜率优化DP
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3719 Solved: 1633[Submit][Stat ...
- bzoj1096[ZJOI2007]仓库建设 斜率优化dp
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5482 Solved: 2448[Submit][Stat ...
- 【BZOJ1096】[ZJOI2007]仓库建设 斜率优化
[BZOJ1096][ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司 ...
- 【bzoj1096】[ZJOI2007]仓库建设 斜率优化dp
题目描述 L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L ...
- P2120 [ZJOI2007]仓库建设 斜率优化dp
好题,这题是我理解的第一道斜率优化dp,自然要写一发题解.首先我们要写出普通的表达式,然后先用前缀和优化.然后呢?我们观察发现,x[i]是递增,而我们发现的斜率也是需要是递增的,然后就维护一个单调递增 ...
- [BZOJ1096] [ZJOI2007] 仓库建设 (斜率优化)
Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天, ...
随机推荐
- python面向对象高级:定制类
Python的class中还有许多这样有特殊用途的函数,可以帮助我们定制类. 比如: __str__ 与__repr____iter____getitem____call__ __str__ 与__r ...
- LinkedList ArrayList 比较
小结: 1.不是同步的,多线程情况下的处理 List list = Collections.synchronizedList(new LinkedList(...)); 2. 快速失败.并发修改异常 ...
- Why is long2ip conversion important?
Frequently Asked Questions about Convert long to IP address https://long2ip.com/faq/ What is long2ip ...
- Jmeter(十一)_针对响应信息不明确的接口做关联
下午写一个新功能的接口脚本,遇到几个技术问题,现在将解决方案写出来 1:做接口关联的时候,发现接口响应没有可以利用的信息.如下图只返回了一个成功的标识,这样的接口如何与之关联? 通过抓包观察后续的修改 ...
- 2018/03/09 每日一个Linux命令 之 chgrp/chown
每日一个Linux命令 2018-03-09 Linux 命令 chgrp/chown chgrp [-参数] [文件或者目录] chown [-参数] [文件所有者]:[文件所属群组] [文件或者目 ...
- java web启动后执行初始化任务
写一个类继承ApplicationListener,可以直接引用下述代码,然后调用相应的方法. package com.linewell.system; import com.linewell.cac ...
- 用Monitor简单3步监控中间件ActiveMQ
Apache ActiveMQ是一个基于JMX规范的纯Java消息中间件,它为应用系统提供高效.灵活的消息同步与异步传输处理.存储转发.可靠传输的特性. 消息队列对于应用的健康运行非常重要,作为运维人 ...
- paas平台
paas平台 定义:PaaS是云计算中重要的一类服务,为用户提供应用的全生命周期管理和相关的资源服务.通过PaaS,用户可以完成应用的构建.部署.运维管理,而不需要自己去搭建计算环境,如安装服务器.操 ...
- requests库的小技巧
#coding:utf-8 import requests # url = 'http://www.baidu.com' # response = requests.get(url) # print ...
- dedecms首页调用随机文章全自动时时更新
dedecms织梦系统是全站生成静态html的,这个对搜索引擎比较友好,但是有时我们要调用文章,让蜘蛛每次来访问都感觉像是有添加新内容一样,要如何做到呢? 可以添加以下dedecms随机文章调用的参数 ...