DP/斜率优化


  Orz Hzwer

八中好像挂了……明天再提交吧……

UPD:2015-03-12 17:24:43

  算了,毕竟是第一道题,还是仔细写一下斜率优化的过程吧。(部分引自Hzwer的题解)

  首先我们根据题意可以列出动规方程 $$ f[i]=min\{ f[j]+cal(j,i) \}$$

  处理$cal(j,i)$可以利用前缀和的思想,令$ sum[i]=\sum_{k=1}^{i} p[k] $

  对于物品$1 ~ i$,如果都从$0$运到$i$,则费用为$(sum[i]-sum[j])*x[i]$

  但由于物品的起始点不都在0,所以对于每个物品$k$可以少花费$x[k]*p[k]$

  定义$b[i]=\sum_{k=1}^{i} (x[k]*p[k]) $

  可得 $ f[i]=min\{ f[j]+(sum[i]-sum[j])*x[i]-(b[i]-b[j])+c[i] \} $

  下面证明决策单调性:

    如果$ j > k $ 且$j$比$k$更优,则有:

\[ \begin{aligned} f[j]+(sum[i]-sum[j])*x[i]-(b[i]-b[j])+c[i] &< f[k]+(sum[i]-sum[j])*x[i]-(b[i]-b[k])+c[i] \\ f[j]-f[k]+b[j]-b[k] &< (sum[j]-sum[k])*x[i] \\ \frac{f[j]-f[k]+b[j]-b[k]}{sum[j]-sum[k]} &< x[i] \end{aligned} \]

  至于为什么要证这个东西请看论文:《动态规划的斜率优化》

  嗯我们现在就知道了对于每个状态$i$,从1 ~ i-1这些决策中的“当前最优决策”是有一个单调性的!比如我们从1开始枚举到 k ,发现 k 是一个最优决策可以更新答案f[i],然后我们继续枚举直到决策 j ,满足上面那个不等式!则表明决策 j 比决策 k 更优!那么有什么用呢?我们根据不等式发现,这个“更优”的属性,只跟 j 和 k 有关,与阶段 i 是无关的!也就是说,当 j 成为一个可选的方案的时候,k 就永远也不用再考虑它了,这就大大减少了转移时的决策数!从而降低了复杂度!

  说的好像很厉害……那具体操作的时候怎么操作呢?

  我们用一个队列q来维护一个斜率单调的决策序列:

 如果slop(q[l],q[l+1])<x[i](参考上面推出的不等式)则说明q[l+1]这个决策比q[l]这个决策更优,所以l++舍弃队首

 算出dp[i]

 如果slop(q[r-1],q[r])>slop(q[r],i),则队尾处不满足单调,所以要弹队尾直到满足单调性(联系凸壳的图形想想)

 插入决策 i 到队列尾部

  当然如果换了一道求max的题,则不等号方向是要改变的……

 /**************************************************************
Problem: 1096
User: Tunix
Language: C++
Result: Accepted
Time:1784 ms
Memory:52052 kb
****************************************************************/ //BZOJ 1096
#include<cstdio>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
int getint(){
int v=,sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=;
typedef long long LL;
/******************tamplate*********************/
int n,l,r,q[N];
LL p[N],x[N],c[N],f[N],b[N],sp[N];
inline double slop(int k,int j){
return double(f[j]-f[k]+b[j]-b[k])/double(sp[j]-sp[k]);
}
int main(){
int n=getint();
F(i,,n){
x[i]=getint(); p[i]=getint(); c[i]=getint();
sp[i]=sp[i-]+p[i]; b[i]=b[i-]+p[i]*x[i];
}
F(i,,n){
while(l<r && slop(q[l],q[l+])<x[i]) l++;
int t=q[l];
f[i]=f[t]-b[i]+b[t]+(sp[i]-sp[t])*x[i]+c[i];
while(l<r && slop(q[r-],q[r])>slop(q[r],i))r--;
q[++r]=i;
}
printf("%lld\n",f[n]);
return ;
}

【BZOJ】【1096】【ZJOI2007】仓库建设的更多相关文章

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

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4201  Solved: 1851[Submit][Stat ...

  2. bzoj 1096: [ZJOI2007]仓库建设 斜率優化

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2242  Solved: 925[Submit][Statu ...

  3. bzoj 1096 [ZJOI2007]仓库建设(关于斜率优化问题的总结)

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3234  Solved: 1388[Submit][Stat ...

  4. 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)*(s ...

  5. 边坡优化主题5——bzoj 1096 [ZJOI2007]仓库建设 解决问题的方法

    [原标题] 1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1998  Solved: 816 [id=10 ...

  6. BZOJ 1096 [ZJOI2007]仓库建设(斜率优化DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1096 [题目大意] 有个斜坡,有n个仓库,每个仓库里面都有一些物品,物品数目为p,仓库 ...

  7. BZOJ 1096 ZJOI2007 仓库建设 边坡优化

    标题效果:特定n植物,其中一些建筑仓库,有一点使,假设没有仓库仓库向右仓库.最低消费要求 非常easy边坡优化--在此之前刷坡优化的情况下,即使这道题怎么错过 订购f[i]作为i点建设化妆i花费所有安 ...

  8. ●BZOJ 1096 [ZJOI2007]仓库建设

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1096 题解: 斜率优化DP $(d_i:i 位置到1位置的距离,p_i:i位置的成品数量,c ...

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

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1096 题意: 有n个工厂,从左往右排成一排,分别编号1到n. 每个工厂里有p[i]件产品, ...

  10. bzoj 1096: [ZJOI2007]仓库建设【斜率优化】

    好眼熟啊 直接dp显然很难算,所以设val为只在n点建一个仓库的费用,然后设f[i]为在i~n点建若干仓库并且i点一定建一个仓库的最大省钱数 转移很显然,设s为p的前缀和,f[i]=max{f[j]+ ...

随机推荐

  1. PHP多例模式

    学习java就知道设计模式中有多例模式: 1.多例类可以有多个实例2.多例类必须能够自我创建并管理自己的实例,并向外界提供自己的实例. 大家都知道PHP单例模式,却很少说PHP多例模式,下面是在wik ...

  2. css font-family 字体全介绍,\5b8b\4f53 宋体 随笔

    font-family采用一种"回退"的形式来保存字体,可以写若干种字体.当第一种字体浏览器不支持的时候,会找第二种字体,一次类推. font-family字体分为两类: 特殊字体 ...

  3. 使用WMIC永久设置你的环境变量

    关于wmic,引用一下这位哥们儿的话http://technet.microsoft.com/en-us/library/bb742610.aspx: WMIC扩展WMI(Windows Manage ...

  4. Python超简单的HTTP服务器

    Python超简单的HTTP服务器 安装了python就可以 python -m SimpleHTTPServer 执行这一个命令即可实现一个HTTP服务器,将当前目录设为HTTP服务目录,可以通过h ...

  5. 【微网站开发】之微信内置浏览器API使用

    最近在写微网站,发现了微信内置浏览器的很多不称心的地方: 1.安卓版的微信内浏览器底部总是出现一个刷新.前进.后退的底部栏,宽度很大,导致屏幕显示尺寸被压缩 2.分享当前网站至朋友圈时,分享的图片一般 ...

  6. 整齐地输出n的平方,立方

    初学C语言,有许多搞不明白的地方.编程,最重要的就是实践.今天,我偶然间看到书上的练习,做了一个能整齐地输出n,n的平方,n的立方的小程序.首先,我先用伪代码设计程序: 提示用户输入表格上限,下限或退 ...

  7. oracle DML错误日志(笔记)

    DML错误日志是oracle10gR2引入的一个类似于SQL*Loader的错误日志功能.它的基本原理是把任何可能导致语句失败的记录转移,放到一张错误日志表中. 具体使用如下: 1.使用DBMS_ER ...

  8. 6.24 AppCan移动开发者大会,我爱我家即将闪亮登场!

    6.24 AppCan移动开发者大会进入倒计时,报名通道即将关闭! “6月24日, 2016AppCan移动开发者大会即将召开,以“平台之上,应用无限”为主题,1500位行业精英汇聚在此,重磅新品发布 ...

  9. node.js的学习

    require('http') 内置模块 server.js var http = require('http'); function start(){ server = http.createSer ...

  10. Linux虚拟机配置本地yum源

    刚开始使用Linux,自己构建了一个Linux虚拟机之后,在使用yum install的时候,经常是出错,提示连接不上. 一直以为是自己构建的虚拟机的问题,后来在网上查找了一些资料,才发现:需要配置本 ...