题意

L公司有N个工厂,由高到底分布在一座山上。

工厂1在山顶,工厂N在山脚。 由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用。

突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏。

由于地形的不同,在不同工厂建立仓库的费用可能是不同的。第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库的费用是Ci。

对于没有建立仓库的工厂,其产品应被运往其他的仓库进行储藏,而由于L公司产品的对外销售处设置在山脚的工厂N,故产品只能往山下运(即只能运往编号更大的工厂的仓库),当然运送产品也是需要费用的,假设一件产品运送1个单位距离的费用是1。

假设建立的仓库容量都都是足够大的,可以容下所有的产品。你将得到以下数据:

  • 工厂i距离工厂1的距离Xi(其中X1=0);
  • 工厂i目前已有成品数量Pi;
  • 在工厂i建立仓库的费用Ci;

请你帮助L公司寻找一个仓库建设的方案,使得总的费用(建造费用+运输费用)最小。

\(N \leq 10^6\)

分析

容易列出dp方程,设\(dp[i]\)表示在\(i\)建仓库,\(1 \sim i\)的最小费用。
\[
dp[i]=\min\limits_{0 \leq j<i} \{dp[j]+x[i]\times\sum\limits_{k=j+1}^{i}(p[k]) -\sum\limits_{k=j+1}^{i}(x[k] \times p[k])\}+c[i]
\]
意思是,运到\(i\)的费用相当于都从\(i\)运到\(1\)的费用减去各自运到\(1\)的费用。

那么设\(sp[i]=\sum_{j=1}^i p[j] , s[i] = \sum_{j=1}^i x[j] * p[j]\),方程就可以化为\(O(n^2)\)。

设\(j > k\),且从\(j\)转移优于从\(k\)转移,可以得到
\[
\frac{(dp[j]+s[j])-(dp[k]+s[k])}{sp[j]-sp[k]}<x[i]
\]
\(sp\)递增,又是小于号,所以维护下凸包。又因为\(x\)单调增,所以可以用单调队列优化。

时间复杂度\(O(n)\)

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<ctime>
#include<cstring>
#define rg register
#define il inline
#define co const
template<class T>il T read()
{
    rg T data=0;
    rg int w=1;
    rg char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        data=data*10+ch-'0';
        ch=getchar();
    }
    return data*w;
}
template<class T>T read(T&x)
{
    return x=read<T>();
}
using namespace std;
typedef long long ll;

co int N=1e6+2;
ll x[N],p[N],c[N];
ll sp[N],s[N],dp[N];

ll Up(int j,int k)
{
    return dp[j]+s[j]-dp[k]-s[k];
}

ll Down(int j,int k)
{
    return sp[j]-sp[k];
}

ll Cal(int i,int j)
{
    return dp[j]+x[i]*(sp[i]-sp[j])-(s[i]-s[j])+c[i];
}

int q[N];

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    int n=read<int>();
    for(int i=1;i<=n;++i)
    {
        read(x[i]),read(p[i]),read(c[i]);
        sp[i]=sp[i-1]+p[i];
        s[i]=s[i-1]+x[i]*p[i];
    }
    int head=0,tail=0;
    q[tail++]=0;
    for(int i=1;i<=n;++i)
    {
        while(head+1<tail&&Up(q[head+1],q[head])<=x[i]*Down(q[head+1],q[head]))
            ++head;
        dp[i]=Cal(i,q[head]);
        while(head+1<tail&&Up(i,q[tail-1])*Down(q[tail-1],q[tail-2])<=Up(q[tail-1],q[tail-2])*Down(i,q[tail-1]))
            --tail;
        q[tail++]=i;
    }
    printf("%lld\n",dp[n]);
    return 0;
}

LG2120 [ZJOI2007]仓库建设的更多相关文章

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

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

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

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

  3. 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3940  Solved: 1736 Description ...

  4. bzoj 1096: [ZJOI2007]仓库建设 斜率優化

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2242  Solved: 925[Submit][Statu ...

  5. bzoj 1096 [ZJOI2007]仓库建设(关于斜率优化问题的总结)

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

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

    dp(v) = min(dp(p)+cost(p,v))+C(v) 设sum(v) = ∑pi(1≤i≤v), cnt(v) = ∑pi*xi(1≤i≤v), 则cost(p,v) = x(v)*(s ...

  7. 边坡优化主题5——bzoj 1096 [ZJOI2007]仓库建设 解决问题的方法

    [原标题] 1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1998  Solved: 816 [id=10 ...

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

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

  9. 斜率优化入门学习+总结 Apio2011特别行动队&Apio2014序列分割&HZOI2008玩具装箱&ZJOI2007仓库建设&小P的牧场&防御准备&Sdoi2016征途

    斜率优化: 额...这是篇7个题的题解... 首先说说斜率优化是个啥,额... f[i]=min(f[j]+xxxx(i,j)) ;   1<=j<i (O(n^2)暴力)这样一个式子,首 ...

随机推荐

  1. 并查集 试水 hdu1232

    #include <stdio.h> #include <stdlib.h> int n,m; ],rank[]; int count; int find(int x) { i ...

  2. float 为什么可以表示很大的整数

    1.float型:单精度浮点数在机内占4个字节,用32位二进制描述(注意:计算机中1个字节=8位). 2.浮点数在机内用指数型式表示,分解为:数符,尾数,指数符,指数四部分. 3.可以算出float型 ...

  3. vue切换路由模式{hash/history}

    vue中常用的路由模式 hash(#):默认路由模式 histroy(/)切换路由模式 切换路由模式 export default new Router({ // 路由模式:hash(默认),hist ...

  4. 解析JDK动态代理实现原理

    JDK动态代理使用实例 代理模式的类图如上.关于静态代理的示例网上有很多,在这里就不讲了. 因为本篇讲述要点是JDK动态代理的实现原理,直接从JDK动态代理实例开始. 首先是Subject接口类. p ...

  5. All Classic Bluetooth profile for iPhone

    iPhone BC profiles Profile Decription HFP1.6 1.通知客户端有电话拨入:2.免提功能:3.音频的输入输出机制. PBAP 1.下载通讯录:2.查找通讯录:3 ...

  6. skynet 创建存储过程脚本

    最近主程更改了数据库的操作方案,由之前的拼写sql脚本转为在mysql端创建好存储过程后,直接调用存储过程. 首先对一个表测试上述过程: 数据库端存储过程:(测试表) CREATE TABLE `ra ...

  7. 使用IDEA将代码托管到GitHub步骤和错误解决

    一.下载并安装Git版本控制工具 下载地址:https://git-scm.com/downloads 注册GitHub账号:https://github.com/ 为什么托管到GitHub要下载Gi ...

  8. CSS3 content属性学习

    css3中出现了 ":before",":after"伪类, 你可以这样写: h1:after{ content:'h1后插入的文本'; ... } 这两个选择 ...

  9. android视图概述

    android视图概述 一.简介 数据和控件分开的作用: 便于引用 便于修改:修改的时候直接改一次数据就可以了

  10. Ajax编程(HTTP请求与响应及API)详解

    AJAX编程 即 Asynchronous [e'sɪŋkrənəs] Javascript And XML, AJAX 不是一门的新的语言,而是对现有技术的综合利用. 本质是在HTTP协议的基础上以 ...