[BZOJ1096] [ZJOI2007]仓库建设
2015-12-18 19:05
302 查看
传送门
http://www.lydsy.com/JudgeOnline/problem.php?id=1096题目大意
给定n个点间的距离,每个点的物品数和建仓库的花费,每个点的物品可以放在该点建的仓库或它后面点建的仓库,运输的费用为距离*物品数题解
x[i]表示位置y[i]物品数量sumy[i]=∑ni=1y[i]sumxy=∑ni=1x[i]∗y[i]x[i]表示位置\\y[i]物品数量\\sumy[i]=\sum_{i=1}^ny[i]\\sumxy=\sum_{i=1}^nx[i]*y[i]dp[i]=min{dp[j]+(sumy[i−1]−sumy[j])x[i]+(sumxy[j]−sumxy[i−1])+cost[i]}dp[i]=min\{dp[j]+(sumy[i-1]-sumy[j])x[i]+(sumxy[j]-sumxy[i-1])+cost[i]\}
dp[i]=min{dp[j]−sumy[j]x[i]+sumxy[j]}+sumy[i−1]x[i]−sumxy[i−1]+cost[i]dp[i]=min\{dp[j]-sumy[j]x[i]+sumxy[j]\}+sumy[i-1]x[i]-sumxy[i-1]+cost[i]
以上为O(n2)O(n^2)的朴素DP
然后我们来斜率优化下
当j<k时取k比取j更优j
dp[j]−sumy[j]x[i]+sumxy[j]<=dp[k]−sumy[k]x[i]+sumxy[k]dp[j]-sumy[j]x[i]+sumxy[j]<=dp[k]-sumy[k]x[i]+sumxy[k]
(dp[j]+sumxy[j])−(dp[k]+sumxy[k])sumy[j]−sumy[k]>=x[i]\frac{(dp[j]+sumxy[j])-(dp[k]+sumxy[k])}{sumy[j]-sumy[k]}>=x[i]
sumxy[],sumy[]都单调,单调队列维护sumxy[],sumy[]都单调,单调队列维护
O(n2)O(n^2)版本
const maxn=1000005; var dp,x,y,sumy,sumxy,cost:array[0..maxn]of int64; i,j,k:longint; n:longint; function min(a,b:int64):int64; begin if a<b then exit(a) else exit(b); end; begin readln(n); sumy[0]:=0; sumxy[0]:=0; for i:=1 to n do begin readln(x[i],y[i],cost[i]); sumy[i]:=sumy[i-1]+y[i]; sumxy[i]:=sumxy[i-1]+x[i]*y[i]; end; dp[1]:=cost[1]; for i:=1 to n do begin dp[i]:=maxlongint; for j:=0 to i-1 do dp[i]:=min(dp[i],dp[j]+(sumy[i-1]-sumy[j])*x[i]+(sumxy[j]-sumxy[i-1])+cost[i]); end; writeln(dp ); end.
斜率优化版本
const maxn=1000005; var dp,x,y,sumy,sumxy,cost:array[0..maxn]of int64; t:array[0..maxn]of longint; i,j,k:longint; n,l,r,tt:longint; function f(a,b:longint):int64; var c:int64; begin c:=(dp[a]+sumxy[a]-dp[b]-sumxy[b]); exit(c); end; begin readln(n); sumy[0]:=0; sumxy[0]:=0; for i:=1 to n do begin readln(x[i],y[i],cost[i]); sumy[i]:=sumy[i-1]+y[i]; sumxy[i]:=sumxy[i-1]+x[i]*y[i]; dp[i]:=sumy[i-1]*x[i]-sumxy[i-1]+cost[i]; end; t[1]:=0; l:=1; r:=1; for i:=1 to n do begin while (l<r)and(f(t[l],t[l+1])>=x[i]*(sumy[t[l]]-sumy[t[l+1]])) do inc(l); tt:=t[l]; dp[i]:=dp[i]+dp[tt]-sumy[tt]*x[i]+sumxy[tt]; while (l<r)and(f(t[r-1],t[r])*(sumy[t[r]]-sumy[i])>f(t[r],i)*(sumy[t[r-1]]-sumy[t[r]])) do dec(r); inc(r); t[r]:=i; end; writeln(dp ); end.
相关文章推荐
- 【jQuery】使用ajax()方法加载服务器数据
- 【工作日志】0004工作日志
- poj 3228 Gold Transportation 二分+网络流
- 第三方支付架构设计之―帐户体系
- 关于图像对比度【4】——对比度调整强度
- adb 和 fastboot 的基本用法详解
- android edittext 点击两次才弹出输入法的解决方法之一
- 总结❤
- 利用java UDP协议,实现简单的双人聊天
- HDU-1075-What Are You Talking About(字典树&map)
- hibernate 实现多表连接查询(转载)
- Swift基础--使用TableViewController自定义列表
- C++ thrift详细教程 及和Protobuf对比
- 【jQuery】使用serialize()方法序列化表单元素值
- VS读取文件或写入文件时出现中文乱码问题
- the begining of coding
- C语言结构体 别名定义
- View的滑动冲突解决-android开发艺术探索笔记
- Activiti进阶(四)——流程变量的设置和获取
- FPGA基础学习之数字时钟设计1