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

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

首先得到dp方程(我竟然自己都每推出了QAQ)$$d[i]=min\{d[j]+cost(j+1,i)\}+c[i]$$其中$d[i]$是前i个且在i建仓库的最小费用,$cost(j+1,i)$是将j+1~i的东西全都运到i的费用

而我们先考虑cost怎么求,orz,好神的前缀和,首先维护sum[i]表示1~i的物品,则j~i的东西从j全都运到i需要$$(sum[i]-sum[j]) \times x[i]$$,然后再设前缀和b[i]表示1~i的物品每一个i从1运到i的费用,则$$cost[j+1,i]=(sum[i]-sum[j]) \times x[i]-(b[i]-b[j])$$其中$$sum[i]=sum[i-1]+p[i], b[i]=b[i-1]+p[i] \times x[i]$$

然后方程变成$$d[i]=min\{d[j]+(sum[i]-sum[j]) \times x[i]-(b[i]-b[j])\}+c[i]$$化简一下可得$$d[i]=min\{d[j]+b[j]-x[i] \times sum[j])\}+c[i]+sum[i] \times x[i]-b[i]$$

而对于这种方程,显然斜率优化。

而斜率优化有几个技巧:

1、不用1D1D直接上斜率,用通俗易懂的方法:

假设决策j<k且k比j优,即:

$$d[k]+b[k]-x[i] \times sum[k]<d[j]+b[j]-x[i] \times sum[j]$$

化简成:

$$\frac{d[k]+b[k]-d[j]-b[j]}{sum[k]-sum[j]}<x[i]$$

因为x[i]单调递增,所以当任意i<L,满足上边不等式,即决策k比j优(在i情况下k比j优的情况时),任意i<L的决策总是大于等于k的,所以当i取最优决策时,i<L的决策单调不降

接下来就是坐标轴的x单调递增,即根据上式,我们可以将点看做(sum[k], d[k]-b[k]),所以可以得到那个斜率方程,这样显然作为坐标轴x的sum[k]是单调不降的,所以得证。

因此这些决策就是二维平面上的点集,想象斜率为x[i]的直线从负无穷向正无穷扫,碰到的第一个点就是最优点(及凸包上的点),理由很简单,因为我们有上边那个不等式,凸包上的点k到任意点j<k的斜率总小于其它不在凸包上的点到任意点的斜率,即k为最优。

那么就维护一个单调队列,斜率递增,然后向求凸包的算法一样在队尾维护凸包即可。

 

2、论文《1D1D动态规划优化初步》上的做法(其实1的做法是这种做法的简便形式)

而之前的某题:【BZOJ】1010: [HNOI2008]玩具装箱toy(dp+斜率优化)

 

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define mkpii make_pair<int, int>
#define pdi pair<double, int>
#define mkpdi make_pair<double, int>
#define pli pair<ll, int>
#define mkpli make_pair<ll, int>
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }
#define printarr1(a, b) for1(_, 1, b) cout << a[_] << '\t'; cout << endl
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; }

const int N=1000005;
int n, q[N], front, tail;
ll x[N], p[N], c[N], sum[N], b[N], f[N];
#define F(x) (f[x]+b[x])
#define E(k,j) (F(k)-F(j))
#define S(k,j) (sum[k]-sum[j])

int main() {
	read(n);
	for1(i, 1, n) read(x[i]), read(p[i]), read(c[i]);
	for1(i, 1, n) sum[i]=sum[i-1]+p[i];
	for1(i, 1, n) b[i]=b[i-1]+p[i]*x[i];
	tail=1;
	for1(i, 1, n) {
		while(front<tail-1 && E(q[front+1], q[front])<x[i]*S(q[front+1], q[front])) ++front;
		int j=q[front];
		f[i]=f[j]+(sum[i]-sum[j])*x[i]-(b[i]-b[j])+c[i];
		while(front<tail-1 && E(q[tail-1], q[tail-2])*S(i, q[tail-1])>E(i, q[tail-1])*S(q[tail-1], q[tail-2])) --tail;
		q[tail++]=i;
	}
	printf("%lld", f[n]);
	return 0;
}

  

 


 

 

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

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位带符号整数。 

 

Source

转载于:https://www.cnblogs.com/iwtwiioi/p/4108902.html

相关推荐

【open judge】【程设】魔兽世界三开战!

#程设 魔兽世界三---开战!--------原以为会很容易ac,没想到写了好久,看来自己的水平还是亟待提高啊!有几个比较有趣的点:1. typeid(#include&lt;typeinfo&gt;)还是比较好用的,特别是本题当战士为wolf,iceman, dragon, ninja时有特殊技能,那么用typeid判断一下就很方便了。2. 对于这种输出很复杂的问题,往往通过使用文件的输入输出再...

weixin_40841416的博客 6051

斜率优化仓库建设

题目描述: SolutionSolutionSolution 一、n3dpn^3dpn3dpdp[i]dp[i]dp[i]表示在第iii个点设立仓库的最小代价。可以通过枚举前一个设置仓库的地方进行转移: dp[i]=min{dp[j]+∑k=j+1i(xi−xk)∗pk}dp[i]=min\{dp[j]+\sum_{k=j+1}^i(x_i-x_k)*p_k\}dp[i]=min{dp[j]+k=j+1∑i​(xi​−xk​)∗pk​} ...

鹭天 266

Windows下Fortran调用CGNS库的完整踩坑实录:从HDF5、CMake到VS2019+IVF2020的保姆级配置

本文详细记录了在Windows环境下使用Fortran调用CGNS库的完整配置过程,涵盖HDF5安装、CMake配置、VS2019IVF2020集成等关键步骤。通过实战经验分享,帮助开发者解决常见编译错误和链接问题,实现高效的FortranCGNS库集成。

weixin_28707739的博客 326

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

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1096 题意:   有n个工厂,从左往右排成一排,分别编号1到n。   每个工厂里有p[i]件产品,到1号工厂的距离为x[i],在此处建一个仓库的花费为c[i]。   现在你需要建造一些仓库,使得所有产品都被运送到仓库中来。   产品只能从左往右运输。每一件产品运输一个单...

a1392136的博客 156

BZOJ1096: [ZJOI2007]仓库建设//斜率优化DP

板子》》》 1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 6758 Solved: 3133 [Submit][Status][Discuss] Description L公司有N个工厂,由高到底分布在一座山上。如图所示,工厂1在山顶,工厂N在山脚。由于这座山处于高原内 陆地区(干燥少雨),L公司一般把...

Up Panda 240

BZOJ1096: [ZJOI2007]仓库建设 斜率优化DP

1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3943  Solved: 1737 [Submit][Status][Discuss] Description   L公司有N个工厂,由高到底分布在一座山上。如图所示,工厂1在山顶,工厂N在山脚。由于这座山处于高原内 陆地区(干燥

Oakley 783

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

Description   L公司有N个工厂,由高到底分布在一座山上。如图所示,工厂1在山顶,工厂N在山脚。由于这座山处于高原内 陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用。突然有一天,L公司的总裁L先生接到气象 部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏。由于 地形的不同,在不同工厂建立仓库的费用可能是不同的。第

TYB的博客 505

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

1096: [ZJOI2007]仓库建设 Time Limit:10 SecMemory Limit:162 MBSubmit:4201Solved:1851[Submit][Status][Discuss] Description   L公司有N个工厂,由高到底分布在一座山上。如图所示,工厂1在山顶,工厂N在山脚。由于这座山处于高原内陆地区(干燥少雨),L公司一般把...

weixin_30540691的博客 98

[斜率优化DP] BZOJ1096: [ZJOI2007]仓库建设

题意有N个工厂按编号顺序排成一条直线,第1个工厂到第i个工厂的距离为dis[i], 第i个工厂一开始堆积着p[i]个货物,现在要紧急把所有货物装进仓库里。在第i个工厂建仓库需要c[i]的代价,对于没有建立仓库的工厂,其货物应被运往其他的仓库进行储藏,且只能往编号大仓库的运,一件货物运送1个单位距离的代价是1。求把所有货物装进仓库的最小代价。 (n<=100000)题解显然是DP,要用到斜率优化

Lynstery's blog 735

bzoj 1096: [ZJOI2007]仓库建设 斜率优化+:DP

bzoj 1096 仓库建设 传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1096 Description L公司有N个工厂,由高到底分布在一座山上。如图所示,工厂1在山顶,工厂N在山脚。 由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用。突然有一天,L公司的总裁L先生接到气象部门的电话,被

DJS_K_D的专栏 569

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

题目链接: 1096: [ZJOI2007]仓库建设 Description   L公司有N个工厂,由高到底分布在一座山上。如图所示,工厂1在山顶,工厂N在山脚。由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用。突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏。由于地形的...

weixin_30566149的博客 113

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

点击这里查看原题典型的斜率优化,主要难点在于如何计算搬运物品的费用,可以维护两个值,tot[i]表示物品总数的前缀和,sum[i]表示将i之前所有物品运到i的总费用,那么将j-i之间所有物品搬运到i的总费用即为去除将1-j之间的物品搬到i的费用,sum[i]-sum[j]-tot[j]*(dis[i]-dis[j])/* User:Small Language:C++ Problem No.:109

SmallSXJ的博客 353

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

https://www.lydsy.com/JudgeOnline/problem.php?id=1096 中文题意不说了, dp【i】表示从1到i所有产品都能放,而且第i个地方一定建仓库的最小费用,转移方程dp[i]=min(dp[j]+Σ(j<k<=i)x[i]-x[k])*p[k](1<=j<i) 用sump表示p的前缀和,用sumpx表示p*x的前缀和,转移方...

weixin_30463341的博客 132

bzoj1096: [ZJOI2007]仓库建设 斜率优化DP

纠结的公式推导。。。g[

WJSZMRX 690

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

[ZJOI2007]仓库建设 Description   L公司有N个工厂,由高到底分布在一座山上。如图所示,工厂1在山顶,工厂N在山脚。由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用。突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是...

weixin_33801856的博客 103

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)*(sum(v)-sum(p)) - (cnt(v)-cnt(p))假设dp(v)dp(i)转移比dp(j)转移优(i>j), 那么 dp(i)+cost(i,v) < dp(j)+cost...

weixin_30871905的博客 117

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

Problem 先有一些工厂,每个工厂有一些成品。先要在其中一些工厂的位置建立仓库,建立仓库会有一定的费用。每个没设立仓库的地方将成品运送至下面的仓库,费用为成品数乘距离。山脚一定有一个仓库。问最少需要的花费是多少 工厂 iii 距离工厂 111 的距离 xix_ixi​(其中 x1=0x_1=0x1​=0); 工厂 iii 目前已有成品数量 pip_ipi​; 在工厂 iii 建立仓库的费用 c...

生活不易,多才多艺 340

BZOJ1096: [ZJOI2007]仓库建设(dp+斜率优化)

Time Limit:10 SecMemory Limit:162 MBSubmit:5790Solved:2597[Submit][Status][Discuss] Description   L公司有N个工厂,由高到底分布在一座山上。如图所示,工厂1在山顶,工厂N在山脚。由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用。突然有一天,L公...

weixin_30788619的博客 126
上一篇: 【BZOJ】1093: [ZJOI2007]最大半连通子图(tarjan+拓扑序)
下一篇: 【BZOJ】1068: [SCOI2007]压缩(dp)
aocong4527
博客等级 码龄10年 6粉丝 230原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值