Description

  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 ≤1000000。

      --by BZOJ
http://www.lydsy.com/JudgeOnline/problem.php?id=1096


首先明确一点,虽然原题是编号小的往编号大处运,但是出于习惯,本人将整个序列翻转,然后题目就变成从大往小运输了
(其实是因为博主一开始读错题了)
首先如果我们已经确定在哪些地方建仓库了,那么有就近运输的原则:
即一个工厂的物品向最近的仓库运输;
即确定了最后一个仓库,在此前面的仓库的数量和位置不影响之后的决策,应使其局部最优;
于是有如下方程:
//f[i]=f[j]+x[j+1]+sum1[i]-sum1[j]-len[j+1]*(s[i]-s[j]);

x[i]:在i建仓库的费用;

len[i]:i到1的距离;

s[i]:前i个工厂的物品和;

sum1[i]:把前i个工厂的物品运至1处的总费用,sum[i]=sum[i-1]+len[i]*(s[i]-s[i-1]);

(再次强调:本人将整个序列翻转,然后题目就变成从大往小运输了)

枚举最后一个仓库的位置为j+1,则前j个位置取最优值f[j],之后的花费是建仓库的x[j+1]和把之后的物品运到j+1位置的费用;

然后因为数据范围,所以需要斜率优化:

//f[i]=f[j]+x[j+1]+sum1[i]-sum1[j]-len[j+1]*(s[i]-s[j]);
//f[i]=-len[j+1]*s[i]+f[j]+x[j+1]-sum1[j]+len[j+1]*s[j]+sum1[i];
//f[i]=Y+sum1[i];
//Y=K*s[i]+B;
//K=-len[j+1];
//B=f[j]+x[j+1]-sum1[j]+len[j+1]*s[j];

维护上凸即可;

代码如下:

#include<cstdio>
#define ll long long
using namespace std;
long long Y(int ,int );
long long K(int );
long long B(int );
int cmp(int ,int ,int );
int n;
int que[];
long long f[],x[],sum1[],len[],s[];
int main()
{
int i,j,k,h=,t=;
long long nu1;
scanf("%d",&n);
for(i=;i<=n;i++){
scanf("%lld%lld%lld",&len[n-i+],&s[n-i+],&x[n-i+]);
}
nu1=len[];
for(i=;i<=n;i++){
len[i]=nu1-len[i];
sum1[i]=sum1[i-]+s[i]*len[i];
s[i]+=s[i-];
}
for(i=;i<=n;i++){
while(h<t&&Y(i,que[h])>=Y(i,que[h+]))h++;
f[i]=(ll)Y(i,que[h])+sum1[i];
while(h<t&&cmp(i,que[t],que[t-]))
t--;
que[++t]=i;
}
printf("%lld",f[n]);
return ;
}
long long Y(int i,int j){
long long k;
k=K(j)*s[i]+B(j);
return k;
}
long long K(int j){
return -len[j+];
}
long long B(int j){
return f[j]+x[j+]-sum1[j]+len[j+]*s[j];
}
int cmp(int x1,int p,int x3){
long long k1=K(x1),k2=K(p),k3=K(x3),b1=B(x1),b2=B(p),b3=B(x3);
ll w1=(k1-k3)*(b2-b1);
ll w2=(k1-k2)*(b3-b1);
return w1<=w2;
}

BZOJP1096[ZJOI2007]仓库建设——solution的更多相关文章

  1. 【洛谷】2120:[ZJOI2007]仓库建设【斜率优化DP】

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

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

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

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

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

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

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

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

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

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

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

  7. 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 ...

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

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

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

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

随机推荐

  1. python-requests库的使用之爬取贴吧内容并保存在本地

    以面向对象的程序设计方式,编写爬虫代码爬去‘李毅吧’所有页面的内容,也可以通过改变对象的参数来爬取其它贴吧页面的内容. 所用到的库为:requests 涉及知识点:python面向对象编程,字符串操作 ...

  2. [java实现]常见算法之字符串操作

    一.字符串反转 把一个句子中的打次进行反转,比如“how are you” ,变为 “you are how” // 字符串反转 public class StringTest { // 字符反转的方 ...

  3. POJ 2192

    #include <iostream> #include <string> #define MAXN 500 using namespace std; bool dp[MAXN ...

  4. C#-类-string/Manth/Random/DateTime-及练习

    类一.string类:.Length 字符串的长度 .Trim() 去掉开头以及结尾的空格.TrimStart() 去掉开头的空格.TrimEnd() 去掉结尾的空格 .ToLower() 全部转换为 ...

  5. docker版redmine安装部署

    数据库准备 docker run -d --name some-postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=redmine postgr ...

  6. Machine learning第四周code 编程作业

    1.lrCostFunction: 和第三周的那个一样的: function [J, grad] = lrCostFunction(theta, X, y, lambda) %LRCOSTFUNCTI ...

  7. [LibreOJ #2983]【WC2019】数树【计数】【DP】【多项式】

    Description 此题含有三个子问题 问题1: 给出n个点的两棵树,记m为只保留同时在两棵树中的边时连通块的个数,求\(y^m\) 问题2: 给出n个点的一棵树,另外一棵树任意生成,求所有方案总 ...

  8. 【实战】某项目SQL注入引发的思考

    数据包: 测试参数:username,测试payload: ' ' or '1'='1 ' or '1'='2 响应结果都未发生任何变化,借助sqlmap测试,结果一样: 尝试在or前面进行简单的fu ...

  9. Linux启动与关闭WIndows服务记录

    启动: mono-service -l:/var/run/Myservice-lock.pid MyService.exe (这个-l参数一定要加上) 控制服务: 暂停: kill -USR1 `ca ...

  10. React 的几个需要注意的地方

    1.写组件时,最好将一个大的组件分解成多个小的组件. 通过React写组件时,应当尽可能地将组件分为更小的更多的组件,然后再复合组件. 比如下面的评论组件就是一个组件,一个庞大的组件,这时我们还没有将 ...