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

来源:互联网 发布:charles能在windows 编辑:程序博客网 时间:2024/06/06 00:12

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

解题方法: 推导过程来自hzwer
f[i]=min(f[j]+cal(j,i))

主要问题是如何在O1的时间内计算cal(j,i),即j+1到i这一段存入i所需的费用

我们可以利用前缀和的思想

sum[i]为p[i]的前缀和

如果所有物品都从0开始运到i,则费用为(sum[i]-sum[j])*x[i]

但由于物品的起始点不在0,所以每个物品可以少花费x[i]*p[i]

b[i]为x[i]*p[i]的前缀和

可得f[i]=min(f[j]+(sum[i]-sum[j])*x[i]-(b[i]-b[j])+c[i]

如果j>k且j比k更优

f[j]-f[k]+b[j]-b[k]<(sum[j]-sum[k])*x[i]。

好了,这就可以直接上斜率优化了。。

代码如下:

#include <bits/stdc++.h>using namespace std;const int maxn = 1000010;typedef long long LL;int n, head, tail, q[maxn];LL p[maxn], x[maxn], c[maxn], dp[maxn];LL sum[maxn], b[maxn];double getxl(int k, int j){ //j > k    return double (dp[j] - dp[k] + b[j] - b[k]) / double(sum[j] - sum[k]);}int main(){    scanf("%d", &n);    for(int i = 1; i <= n; i++) scanf("%lld%lld%lld", &x[i], &p[i], &c[i]);    sum[0]= b[0] = 0;    for(int i = 1; i <= n; i++){        sum[i] = sum[i-1] + p[i];        b[i] = b[i-1] + x[i] * p[i];    }    for(int i = 1; i <= n; i++){        while(head < tail && getxl(q[head], q[head+1]) < x[i]) head++;        int t = q[head];        dp[i] = dp[t] + (sum[i] - sum[t]) * x[i] - b[i] + b[t] + c[i];        while(head < tail && getxl(q[tail], i) < getxl(q[tail-1], q[tail])) tail--;        q[++tail] = i;    }    cout << dp[n] << endl;    return 0;}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 生僻字打不出来怎么办 名字里有生僻字怎么办 qq语音红包生僻字怎么办 生僻字上不了户口怎么办 7岁儿童结巴怎么办 小孩咳喘有痰怎么办 都说我不爱说话怎么办 宝宝突然结巴了怎么办 淘宝客户不理人怎么办 遇到不说话客户怎么办 同学群没人聊怎么办 群里没人说话怎么办 儿童说话声音沙哑怎么办 孩子不和外人说话怎么办 同学退群该怎么办 宝宝睡觉枕头湿怎么办 一个多月的小宝宝便秘怎么办 小宝宝便秘拉屎困难怎么办 一岁小宝宝便秘怎么办 客户不听我说话怎么办 微信上客户不理怎么办 小宝宝母乳不够吃怎么办 小宝宝吃母乳拉肚子怎么办 母乳小宝宝吃奶吃不了怎么办 婴儿感冒吐奶怎么办 小孩感冒吐奶怎么办 小孩吐奶怎么办月子 新生儿一直吐奶怎么办 宝宝50天吐奶厉害怎么办 小儿吐奶厉害怎么办 宝宝一直便秘了怎么办 误建了微信群聊怎么办 新生儿大口吐奶怎么办 宝宝喝了就吐奶怎么办 婴儿顿顿吐奶怎么办 说话着急就结巴怎么办 幼儿舌头长泡怎么办 一着急说话结巴怎么办 幼儿舌头又溃疡怎么办 3儿童说话结巴怎么办 孩子小舌头短怎么办?