BZOJ 1096: [ZJOI2007]仓库建设( dp + 斜率优化 )
2015-09-04 00:01
330 查看
![](http://images2015.cnblogs.com/blog/723896/201509/723896-20150903235049575-796918043.png)
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)*(sum(v)-sum(p)) - (cnt(v)-cnt(p))
假设dp(v)由dp(i)转移比dp(j)转移优(i>j),
那么 dp(i)+cost(i,v) < dp(j)+cost(j,v)
即 dp(i)+x(v)*(sum(v)-sum(i))-(cnt(v)-cnt(i)) < dp(j)+x(v)*(sum(v)-sum(j))-(cnt(v)-cnt(j))
设f(x) = dp(x)+cnt(x), 化简得 (f(i)-f(j)) / (sum(i)-sum(j)) < x(v)
然后就斜率优化, 单调队列维护一个下凸函数
-----------------------------------------------------------------------
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1000009; ll sum[maxn], cnt[maxn], dp[maxn];int x[maxn], N, Q[maxn]; inline double slope(int a, int b) { return (double) (dp + cnt[b] - dp[a] - cnt[a]) / (sum[b] - sum[a]);} int main() { scanf("%d", &N); dp[0] = cnt[0] = sum[0] = 0; for(int i = 1; i <= N; i++) { int p; scanf("%d%d%lld", x + i, &p, dp + i); sum[i] = sum[i - 1] + p; cnt[i] = cnt[i - 1] + ll(p) * x[i]; } int qh = 0, qt = 1; Q[0] = 0; // Q [qh, qt) for(int i = 1; i <= N; i++) { while(qt - qh > 1 && slope(Q[qh], Q[qh + 1]) < x[i]) qh++; int best = Q[qh]; dp[i] += dp[best] + ll(x[i]) * (sum[i] - sum[best]) - cnt[i] + cnt[best]; while(qt - qh > 1 && slope(Q[qt - 2], Q[qt - 1]) >= slope(Q[qt - 1], i)) qt--; Q[qt++] = i; } printf("%lld\n", dp
); return 0;[b]}-----------------------------------------------------------------------
1096: [ZJOI2007]仓库建设
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3001 Solved: 1286
[Submit][Status][Discuss]
Description
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公司寻找一个仓库建设的方案,使得总的费用(建造费用+运输费用)最小。Input
第一行包含一个整数N,表示工厂的个数。接下来N行每行包含两个整数Xi, Pi, Ci, 意义如题中所述。Output
仅包含一个整数,为可以找到最优方案的费用。Sample Input
30 5 10
5 3 100
9 6 10
Sample Output
32HINT
在工厂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位带符号整数。
Source
相关文章推荐
- Java enum
- wemall单页化与wemall微分销
- 使用对象去暂停或锁住一个线程的方式
- 回调机制的实现,即细看setOnClickListener怎么运行
- Android ListView中使用CheckBox等的混乱问题
- php开发app接口
- 网站代码优化--网站代码优6化的宗述
- 初学数模-MATLAB Quick Start! Part I
- Ubuntu安装visual-studio-code
- Dalvik虚拟机运行过程分析
- 【POJ3041】【最大二分匹配=最小覆盖点数】
- 【算法设计与数据结构】二分法解决最大值最小化问题—进阶篇— URAL 2034 Caravans
- MongoDB学习十三 --MongoDB的Java增删除改查
- 和朋友聊天趣事
- HTML5与CSS3权威指南 - 笔记
- 算法——插入排序
- 网络爬虫——网络爬虫的发展
- 剑指Offer面试题:22.二叉搜索树的后序遍历序列
- OC变量数据类型
- 面向对象的设计思想