斜率优化 【ZJOI 2007】仓库建设 bzoj1096
来源:互联网 发布:英文小说优美 知乎 编辑:程序博客网 时间:2024/05/21 17:42
题目大意:
有n个工厂,每个工厂到第一个工厂的距离为li,每个工厂有pi件货物,现在需要在一些工厂上建设仓库存储货物,费用为costi。
工厂i的物品可以在i~n的工厂内存放,运送到工厂j需要(lj-li)*pi的费用。
求存放所有货物的最小花费。
题目分析:
可以容易的想到动态规划。
设f[i]代表在i位置建立工厂,存放1~i的货物的最小花费。
设sum[i]=∑(1~i)pi (代表前i个工厂的物品和)
设trans[i]=∑(1~i)sum[i-1]*(l[i]-l[i-1]) (代表把所有物品运送至工厂i的花费)
递推公式为:
f[i]=min{f[j]+trans[i]-trans[j]-sum[j]*(l[i]-l[j]+cost[i])}
(枚举前面的每一个位置j,j之前的答案为f[j],f[i]的答案即为f[j]加上j到i之间所有货物运送到位置i的费用,不过这里不是重点)
这样做时间复杂度是O(n^2)的,显然时间爆炸。
考虑优化。
假设i位置的答案可由位置j转移。
f[i]=f[j]+trans[i]-trans[j]-sum[j]*(l[i]-l[j]+cost[i])
把括号打开,把和i相关的放到一起,把和j相关的放到一起:
f[i]-trans[i]-cost[i]=f[j]+sum[j]*l[j]-trans[j]-sum[j]*l[i]
设P=f[i]-trans[i]-cost[i]
设y=f[j]+sum[j]*l[j]-trans[j]
设x=sum[j]
设k=l[i]
于是上述式子就转化为: P=y-kx
即y=kx+P,为一次函数形式。
此时除了要求的f[i]与i有关的值都可以视为定值,所以斜率k为定值。
可以将有关j的答案看做是平面上的一些点,我们现在想要求f[i]的最小值,即求P的最小值。
我们可以通过严格的证(hua)明(tu)得知,最优解一定在凸包所代表的点上:
并且观察到最优答案点左侧的斜率小于k,右侧斜率大于k,只要直接找到这个点直接更新答案即可。
观察发现:x是递增的,所以凸包可以线性维护。
观察发现:k是递增的,所以答案点在凸包上也是递增的,所以可以线性查找,直接向右找。
这样更新答案是线性时间复杂度。
总时间复杂度为O(n)。
代码如下:
#include <cstdio>#define N 1200000using namespace std;typedef long long LL;struct point{ LL x,y; point(LL x=0,LL y=0):x(x),y(y){} LL operator * (const point &c) const { return x*c.y-y*c.x; } point operator - (const point &c) const { return point(x-c.x,y-c.y); }}h[N];int n;LL l[N],sum[N],trans[N],f[N],cost[N];int top=0;void convex_hull(point x){ while(top>1 && (h[top]-h[top-1])*(x-h[top-1])<=0) top--; h[++top]=x; return;}bool judge(int now,long long k){ if(now!=top && h[now+1].y-h[now].y<k*(h[now+1].x-h[now].x)) return false; return true;}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lld%lld%lld",&l[i],&sum[i],&cost[i]); sum[i]+=sum[i-1]; trans[i]=trans[i-1]+sum[i-1]*(l[i]-l[i-1]); } int now=1; convex_hull(point(0,0)); for(int i=1;i<=n;i++) { while(!judge(now,l[i])) now++; f[i]=h[now].y-l[i]*h[now].x+trans[i]+cost[i]; convex_hull(point(sum[i],f[i]+sum[i]*l[i]-trans[i])); now=now>top?top:now; } printf("%lld\n",f[n]); return 0;}
- 斜率优化 【ZJOI 2007】仓库建设 bzoj1096
- [BZOJ1096][ZJOI2007][DP][斜率优化]仓库建设
- bzoj1096: [ZJOI2007]仓库建设 斜率优化DP
- [BZOJ1096]ZJOI2007仓库建设|斜率优化DP
- 【BZOJ1096】[ZJOI2007]仓库建设【斜率优化】
- 【bzoj1096】[ZJOI2007]仓库建设 斜率优化DP
- 【bzoj1096】【ZJOI2007】【仓库建设】【斜率优化dp】
- 【BZOJ1096】仓库建设,斜率优化DP练习
- BZOJ1096: [ZJOI2007]仓库建设 斜率优化DP
- 【bzoj1096】仓库建设 斜率优化dp
- [斜率优化DP] BZOJ1096: [ZJOI2007]仓库建设
- 【斜率优化DP】BZOJ1096 [ZJOI2007]仓库建设
- DP--斜率优化--BZOJ1096--仓库建设
- bzoj1096 [ZJOI2007]仓库建设(斜率优化)
- bzoj1096[ZJOI2007]仓库建设 斜率优化dp
- BZOJ1096(ZJOI2007)仓库建设--斜率优化DP
- bzoj1096 [ZJOI2007]仓库建设 斜率优化dp
- BZOJ 1096 ZJOI 2007 仓库建设 斜率优化DP
- Hibernate一级缓存(基于查询分析)
- WebAssembly,Web的新时代
- 通过浏览器打开本地Activity
- 2017.3.4 pat甲级B题Chain the Ropes
- beautifulsoup在windows下的安装
- 斜率优化 【ZJOI 2007】仓库建设 bzoj1096
- 80:Path Sum
- 位域复习
- 题目1001:A+B for Matrices
- 小写字母到大写字母的转换
- android网络请求问题:android.os.NetworkOnMainThreadException
- 廖雪峰python教程阅读之数据类型和变量
- 反射7
- CSS居中小技巧