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公司一般把产品直接堆放在露天,以节省费用.突然有一天, ...
随机推荐
- js判断字符串长度
方法1: String.prototype.gblen = function() { var len = 0; for (var i=0; i<this.length; i++) { if (t ...
- windows dos命令大全
windows dos命令大全 一.windows DOS命令概述 Windows的dos命令又是Windows的CMD命令.而cmd命令又是原来MS-DOS系统保留下来. DOS来源路径与配置对应的 ...
- 混淆矩阵在Matlab中PRtools模式识别工具箱的应用
声明:本文用到的代码均来自于PRTools(http://www.prtools.org)模式识别工具箱,并以matlab软件进行实验. 混淆矩阵是模式识别中的常用工具,在PRTools工具箱中有直接 ...
- 解压赋值及python的一些基础运算
#解压赋值lis=[11,22,33,44,55] money1,money2,money3,money4,money5=lis print(money1,money2,money3,money4,m ...
- The Die Is Cast(poj 1481简单的双dfs)
http://poj.org/problem?id=1481 The Die Is Cast Time Limit: 1000MS Memory Limit: 10000K Total Submi ...
- oj2892(字典树)
一改时间以后WA了,我就知道这题是考字典树,可惜代码怎么也不会敲了,郁闷. #include <stdio.h>#include <string.h>#include < ...
- 页面加载之window.onload=function(){} 和 $(function(){})的区别
通用的页面加载js有四种方式: 1.window.onload = function(){}; —-js 2.$(window).load(function(){});——Jquery 3.$(doc ...
- PAT 1016 Phone Bills[转载]
1016 Phone Bills (25)(25 分)提问 A long-distance telephone company charges its customers by the followi ...
- 使用tagName定位报错
使用标签进行定位元素,页面报错,由于input标签不唯一,webdriver默认会取第一个元素,但是第一个input元素的类型是‘hidden’,无法展示,因此程序就报错了 如何解决,未完待续...
- weka数据挖掘拾遗(二)---- 特征选择(IG、chi-square)
一.说明 IG是information gain 的缩写,中文名称是信息增益,是选择特征的一个很有效的方法(特别是在使用svm分类时).这里不做详细介绍,有兴趣的可以googling一下. chi-s ...