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 仓库建设 -斜率优化的更多相关文章

  1. bzoj 1096 仓库建设 —— 斜率优化DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1096 设 f[i] 为 i 作为最后一个仓库时前 i 个工厂的答案,最后的答案当然是 f[n ...

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

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

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

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

  4. 【BZOJ-1096】仓库建设 斜率优化DP

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

  5. bzoj1096[ZJOI2007]仓库建设 斜率优化dp

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

  6. 【BZOJ1096】[ZJOI2007]仓库建设 斜率优化

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

  7. 【bzoj1096】[ZJOI2007]仓库建设 斜率优化dp

    题目描述 L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L ...

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

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

  9. [BZOJ1096] [ZJOI2007] 仓库建设 (斜率优化)

    Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天, ...

随机推荐

  1. Linux下搭建hadoop开发环境-超详细

    先决条件:开发机器需要联网 已安装java 已安装Desktop组 1.上传安装软件到linux上: 2.安装maven,用于管理项目依赖包:以hadoop用户安装apache-maven-3.0.5 ...

  2. flask 日志

    https://www.polarxiong.com/archives/Flask%E4%BD%BF%E7%94%A8%E6%97%A5%E5%BF%97%E8%AE%B0%E5%BD%95%E5%8 ...

  3. SQL SERVER 2008 误删数据且无全备恢复方法

    原文:http://www.jb51.net/article/84932.htm SQL Server中误删除数据的恢复本来不是件难事,从事务日志恢复即可.但是,这个恢复需要有两个前提条件: 1. 至 ...

  4. 腾讯在线文档发布:实现QQ、微信多平台多人协作编辑

    18日,腾讯宣布推出专注多人协作的在线文档产品—腾讯文档,据介绍,腾讯文档是一款支持随时随地创建.编辑的多人协作式在线文档工具,拥有一键翻译.实时股票函数和浏览权限安全可控等功能,以及打通QQ.微信等 ...

  5. PHPExcel使用-使用PHPExcel导入文件

    导入步骤: 1. 实例化excel读取对象 2. 加载excel文件 ----------------> ( 1>. 全部加载. 2>. 选择加载. ) 3. 读取excel文件 - ...

  6. Spark Sort Based Shuffle内存分析

    分布式系统里的Shuffle 阶段往往是非常复杂的,而且分支条件也多,我只能按着我关注的线去描述.肯定会有不少谬误之处,我会根据自己理解的深入,不断更新这篇文章. 前言 借用和董神的一段对话说下背景: ...

  7. python排序函数sort()与sorted()区别

    sort是容器的函数:sort(cmp=None, key=None, reverse=False) sorted是python的内建函数:sorted(iterable, cmp=None, key ...

  8. MySQL主从复制(Replication for Backup)

    环境:MySQL5.7,VMware-Workstation-12-Pro,Windows-10,CentOS-7.5,Xshell5 1. 基本概念和操作思路 主从复制能做什么 数据库的主从复制,是 ...

  9. Ubuntu 16.04下deb文件的安装

    pkg 是Debian Package的简写,是为Debian 专门开发的套件管理系统,方便软件的安装.更新及移除.所有源自Debian的Linux发行版都使用dpkg,例如Ubuntu.Knoppi ...

  10. rsync 常用命令

    rsync -auvrtzopgP --progress --delete --exclude-from=exclude.list SRC DST \\保留原文件属性并详细输出 删除那些DST中SRC ...