*题目描述:

  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公司寻找一个仓库建设的方案,使得总的费用(建造费用+运输费用)最小。

*输入:
  第一行包含一个整数N,表示工厂的个数。接下来N行每行包含两个整数Xi, Pi, Ci, 意义如题中所述。

*输出:
  仅包含一个整数,为可以找到最优方案的费用。

*样例输入:
3
0 5 10
5 3 100
9 6 10

*样例输出:
32

*提示:
在工厂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方程:
fi=mini−1j=1(fj+calc(j+1,i)+ci)。
计calc(j,i) 表示区间[j,i] 内的所有货物全部运送到i节点所需要的代价,fi 表示第i号节点建成仓库所需要的最小代价。
这里如果计算calc(j,i) 的值我是参考hzwer学长的题解的,丢链接跑。
首先我们先假设所有的货物都从1号节点出发,计sumi 为 pi 的前缀和,那么区间内的货物从1号节点到i号节点的费用就是(sumi−sumj)∗xi 。然后每个节点的货物可以少运送的费用为xi∗pi 。于是我们计bi 为 xi∗pi 的前缀和。然后DP的转移方程就变成了:
fi=mini−1j=1(fj+(sumi−sumj)∗xi−(bi−bj)+ci)
将式子稍微转化即可变成我们熟悉的斜率优化的形式:
fi=sumi∗xi+ci−bi+mini−1j=1(fj+bj−sumj∗xi)
比较斜率优化的式子yj−ki∗xj,此时,fj+bj 就是点的纵坐标 yj,sumj 就是点横坐标 xj,xi 就是斜率ki。又因为这题里面斜率ki 和横坐标xj 都是单调的,所以我们可以用单调队列来维护凸包,复杂度O(n)。

*代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath> #ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif #ifdef CT
#define debug(...) printf(__VA_ARGS__)
#define setfile()
#else
#define debug(...)
#define filename ""
#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout)
#endif #define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
#define cabs(_x) ((_x) < 0 ? (- (_x)) : (_x))
char B[1 << 15], *S = B, *T = B;
inline int F()
{
R char ch; R int cnt = 0; R bool minus = 0;
while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
ch == '-' ? minus = 1 : cnt = ch - '0';
while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
return minus ? -cnt : cnt;
}
#define maxn 1000010
int x[maxn], p[maxn], c[maxn], q[maxn];
long long b[maxn], sum[maxn], f[maxn];
#define x(_i) (sum[_i])
#define y(_i) (f[_i] + b[_i])
inline double slope(R int i, R int j)
{
return (double) (y(i) - y(j)) / (x(i) - x(j));
}
int main()
{
// setfile();
R int n = F();
for (R int i = 1; i <= n; ++i)
{
x[i] = F();
p[i] = F();
c[i] = F();
sum[i] = sum[i - 1] + p[i];
b[i] = b[i - 1] + 1ll * p[i] * x[i];
}
/*
memset(f, 63, sizeof (f)); f[0] = 0;
for (R int i = 1; i <= n; ++i)
{
for (R int j = 0; j < i; ++j)
cmin(f[i], f[j] + (sum[i - 1] - sum[j]) * x[i] - b[i - 1] + b[j] + c[i]);
}
*/
R int h = 1, t = 1;
q[h] = 0;
for (R int i = 1; i <= n; ++i)
{
while (h < t && slope(q[h], q[h + 1]) < x[i]) ++h;
R int j = q[h];
f[i] = f[j] + (sum[i] - sum[j]) * x[i] - b[i] + b[j] + c[i];
while (h < t && slope(q[t - 1], i) < slope(q[t - 1], q[t])) --t;
q[++t] = i;
}
printf("%lld\n", f[n] );
return 0;
}
/*
3
0 5 10
5 3 100
9 6 10
*/

【bzoj1096】[ZJOI2007]仓库建设的更多相关文章

  1. BZOJ1096 ZJOI2007 仓库建设 【斜率优化DP】

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

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

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

  3. Bzoj1096 [ZJOI2007]仓库建设

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4193  Solved: 1845 Description L公司有N个工厂,由高到底分布在一座山上. ...

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

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

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

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

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

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5790  Solved: 2597[Submit][Status][Discuss] Descript ...

  7. BZOJ1096 [ZJOI2007]仓库建设 动态规划 斜率优化

    原文链接http://www.cnblogs.com/zhouzhendong/p/8696410.html 题目传送门 - BZOJ1096 题意 给定两个序列$a,b,X$,现在划分$a$序列. ...

  8. 2018.09.07 bzoj1096: [ZJOI2007]仓库建设(斜率优化dp)

    传送门 斜率优化dp经典题. 令f[i]表示i这个地方修建仓库的最优值,那么答案就是f[n]. 用dis[i]表示i到1的距离,sump[i]表示1~i所有工厂的p之和,sum[i]表示1~i所有工厂 ...

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

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1096 分析: 假设1~10,如果在3 6 10建立仓库,那么当前建立仓库决策下的最优值 ...

  10. BZOJ1096 [ZJOI2007]仓库建设——斜率优化

    方程: $\Large f(i)=min(f(j)+\sum\limits_{k=j+1}^{i}(x_i-x_k)*p_k)+c_i$ 显然这样的方程复杂度为$O(n^3)$极限爆炸,所以我们要换一 ...

随机推荐

  1. 【MM系列】SAP MM物料账在制品承担差异功能及配置

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP MM物料账在制品承担差异功能 ...

  2. Scratch少儿编程系列:(一)版本的选择及安装

    工欲善其事必先利其器,为了使用Scratch,首先要到官网上下载相关软件. 官网链接地址为:https://scratch.mit.edu/download,我用的是Windows系统,下载对应的安装 ...

  3. Snow的追寻--线段树维护树的直径

    Snow终于得知母亲是谁,他现在要出发寻找母亲.王国中的路由于某种特殊原因,成为了一棵有n个节点的根节点为1的树,但由于"Birds are everywhere.",他得到了种种 ...

  4. java创建多线程实现并行计算任务处理

    1.直接上代码一看明白: package multithreadingTest; class fblib extends Thread{ public static Integer fb(Intege ...

  5. 学了一天的golang从入门到放弃

    Google的go就是个二货,不实用,它最多只能和c比简单.low!

  6. switch条件变量的取值类型

    switch条件变量的取值类型主要有以下六种: 1)JDK1.5(不含JDK1.5)之前只能是byte.short.int.char类型,不能是float.double.long.boolean类型. ...

  7. [转帖]Oracle 使用sqlnet.ora/trigger限制/允许某IP或IP段访问指定用户

    Oracle 使用sqlnet.ora/trigger限制/允许某IP或IP段访问指定用户 原创 Oracle 作者:maohaiqing0304 时间:2016-05-03 17:05:46  17 ...

  8. Java——LinkedList底层源码分析

    1.简介 LinkedList 是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢.另外,他还提供了 List 接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈 ...

  9. [2019上海网络赛J题]Stone game

    题目链接 CSLnb! 题意是求出给定集合中有多少个合法子集,合法子集的定义为,子集和>=总和-子集和$\& \&$子集和-(子集的子集和)<=总和-子集和. 其实就是很简 ...

  10. SharePoint自己定义程序页面部署 不用重新启动IIS

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/dz45693/article/details/30840255 SharePoint的部署方式默认是 ...