[BZOJ]1096: [ZJOI2007]仓库建设 斜率优化DP
2016-11-29 14:04
323 查看
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
30 5 10
5 3 100
9 6 10
Sample Output
32首先推出简单的DP方程:
f[i]=min(f[j]+x[i]*(s[i-1]-s[j])-ch[i-1]+ch[j])+c[i];(ch和s的具体含义见代码)
然后我们就开始往斜率优化的方向想。
假设j1<j2<i,并且j2、j1对于当前的i来说,j2更优(不差于j1)
f[j2]-x[i]*s[j2]+ch[j2]<=f[j1]-x[i]*s[j1]+ch[j1]
然后证明对于i以后的t,也是如此
设x[t]=x[i]+v
f[j2]-(x[i]+v)*s[j2]+ch[j2]<=f[j1]-(x[i]+v)*s[j1]+ch[j1]
f[j2]-x[i]*s[j2]-v*s[j2]+ch[j2]<=f[j1]-x[i]*s[j1]-v*s[j1]+ch[j1]
因为 f[j2]-x[i]*s[j2]+ch[j2]<=f[j1]-x[i]*s
10272
[j1]+ch[j1]
又因为 -v*s[j2]<=-v*s[j1] (显而易见s[j2]>s[j1])
所以得证
接下来推斜率方程
f[j2]-x[i]*s[j2]+ch[j2]<=f[j1]-x[i]*s[j1]+ch[j1]
((f[j2]+ch[j2])-(f[j1]+ch[j1]))/(s[j2]-s[j1])<=x[i]
这样这道题目就搞定了。
这道题目是我人生中第一次独立推斜率方程,代码也因为一点问题,会有一点bug(FYC神奇方法)。
#include<cstdio> #include<cstring> const int Q=1000005; long long x[Q],p[Q],c[Q]; long long s[Q],ch[Q]; long long f[Q],q[Q]; long long mymin(int u1,int u2) { if (u1<u2) return u1; return u2; } double Y(int j) {return 1.0*(f[j]+ch[j]);} double X(int j) {return 1.0*s[j];} double slop(int j1,int j2) {return (Y(j1)-Y(j2))/(X(j1)-X(j2));} int main() { int n; scanf("%d",&n); //j~i 的人全部到i -> p[j]*(x[i]-x[j])+p[j+1]*(x[i]-x[j+1])+```+p[i-1]*(x[i]-x[i-1]) // x[i]*(p[j]+p[j+1]+```p[i-1]) -xj*pj-x[j+1]*p[j+1]-```-x[i-1]*p[i-1] s[0]=ch[0]=0; for (int i=1;i<=n;i++) { scanf("%lld%lld%lld",&x[i],&p[i],&c[i]); s[i]+=s[i-1]+p[i]; ch[i]+=ch[i-1]+x[i]*p[i]; } int l=1,r=1;q[1]=0; for(int i=1;i<=n;i++) { while(l<r && slop(q[l],q[l+1])<=x[i]) l++; int j=q[l]; f[i]=f[j]+x[i]*(s[i-1]-s[j])-ch[i-1]+ch[j]+c[i]; while(l<r && slop(q[r-1],q[r])>slop(q[r],i)) r--; q[++r]=i; } printf("%lld",f ); }
相关文章推荐
- [BZOJ1096][ZJOI2007]仓库建设(斜率优化dp)
- 【BZOJ】1096: [ZJOI2007]仓库建设(dp+斜率优化)
- BZOJ 1096: [ZJOI2007]仓库建设 | 斜率优化DP
- [BZOJ1096][ZJOI2007]仓库建设(斜率优化DP)
- [BZOJ1096][ZJOI2007]仓库建设(斜率优化dp)
- BZOJ1096: [ZJOI2007]仓库建设 斜率优化DP
- BZOJ 1096: [ZJOI2007]仓库建设 [斜率优化DP]
- [省选前题目整理][BZOJ 1096][ZJOI2007]仓库建设(斜率优化DP)
- bzoj1096[ZJOI2007]仓库建设 斜率优化dp
- BZOJ 1096 ZJOI 2007 仓库建设 斜率优化DP
- BZOJ 1096 [ZJOI2007]仓库建设 斜率优化dp
- BZOJ 1096 [ZJOI2007]仓库建设(斜率优化DP)
- 【ZJOI2007】【BZOJ1096】仓库建设(斜率优化DP)
- [BZOJ 1096][ZJOI2007]仓库建设:DP斜率优化
- 【bzoj1096】[ZJOI2007]仓库建设 斜率优化DP
- BZOJ1096 [ZJOI2007]仓库建设(斜率优化dp)
- BZOJ1096(ZJOI2007)仓库建设--斜率优化DP
- [BZOJ1096]ZJOI2007仓库建设|斜率优化DP
- 【bzoj1096】【ZJOI2007】【仓库建设】【斜率优化dp】
- BZOJ 1096 [ZJOI2007]仓库建设 斜率优化dp