*题目描述:

  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. Numpy——进阶篇

    impoort numpy as np arr=np.arange(10) #输出奇数 arr[arr%2==1] #将arr中的所有奇数替换为-1,而不改变arr out=np.where(arr% ...

  2. xmake入门,构建项目原来可以如此简单

    前言 在开发xmake之前,我一直在使用gnumake/makefile来维护个人C/C++项目,一开始还好,然而等项目越来越庞大后,维护起来就非常吃力了,后续也用过一阵子automake系列工具,并 ...

  3. 获取kafka最新offset-java

    之前笔者曾经写过通过scala的方式获取kafka最新的offset 但是大多数的情况我们需要使用java的方式进行获取最新offset scala的方式可以参考: http://www.cnblog ...

  4. qt 获取磁盘空间大小,cpu利用率,内存使用率

    转自:http://www.qtcn.org/bbs/read-htm-tid-60613.html. 1:封装成一个类,直接调用即可.已经在多个商业项目中使用.2:所有功能全平台 win linux ...

  5. uboot常用命令

    一. 常用简单命令 1.1. help命令 a. 帮助查看其他命令的使用方法,类型linux下man b. 示例: help help x210 # help help help [command . ...

  6. Python设置

    1.中断程序执行 在命令行中中断正在执行的程序,ctrl c或者ctrl break 2.SyntaxError: Non-ASCII character 需要在最开始的地方加上 : #-*-codi ...

  7. 又一Tab切换效果(js实现)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. MySql+EF+CodeFirst

    ef+mssql详细是许多.net程序员的标配.作为一个程序员当然不能只会mssql这一个数据库,今天简单聊聊ef+mysql.推荐新人阅读. 1]首先创建一个mvc项目,如图: 创建完毕之后再nug ...

  9. python 框架

    支持异步的 python web 框架 tornado 轻量级 flask 框架 flask中文文档 import base64 import random import io import time ...

  10. windows安装nginx部署

    转自:https://www.jb51.net/article/47066.htm 一.下载安装Nginx(本文环境为windows xp 32bit环境) 解压nginx-1.0.11.zip,进入 ...