原文链接http://www.cnblogs.com/zhouzhendong/p/8696410.html

题目传送门 - BZOJ1096

题意

  给定两个序列$a,b,X$,现在划分$a$序列。

  被划分出来的段$[j,i]$的花费为$a_i+\sum_{k=j+1}^{i}(X_i-X_k)b_k$。

  一种划分方式的花费就是每一段的花费之和。

  问最小花费。

  序列长度$\leq 10^6$。

题解

  这题是BZOJ3437的升级版(其实也没升多少……,不仅代码我是几乎原样复制到,连题解我几乎都是原样复制的……)

  首先我们不难写出DP方程:

  $$dp_i=max\{dp_j+\sum_{k=j+1}^{i}(X_i-X_k)b_k\}+a_i\ \ \ \ \ (0\leq j<i)$$

  然后容易看出可以斜率优化。

  然后搬出斜率优化的套路。

  先化简些式子。

  $$dp_j+\sum_{k=j+1}^{i}(X_i-X_k)b_k\\=dp[j]-\sum_{k=j+1}^{i}X_kb_k+X_i\sum_{k=j+1}^{i}b_k$$

  设:

  $$sum_i=\sum_{j=1}^{i}b_j$$

  $$vsum_i=\sum_{j=1}^{i}b_j\times X_j$$

  则原式=

  $$dp_j-vsum_i+vsum_j+X_isum_i-X_isum_j$$

  然后开始斜率优化DP的套路部分:

  设(注意$x$的大小写)

  $$x_i=sum_i$$

  $$y_i=dp_i+vsum_i$$

  则原式=

  $$y_j-vsum_i+X_isum_i-X_ix_j$$

  假设$j>k$且从$j$转移不劣于$k$,则:

  $$y_j-vsum_i+X_isum_i-X_ix_j\leq y_k-vsum_i+X_isum_i-X_ix_k$$

  化简得:

  $$\frac{y_j-y_k}{x_j-x_k}\leq X_i$$

  然后献上斜率优化DP套路:

  注意由于开始限制了$j>k$所以$x_j-x_k>0$,所以最后两边同时相除不等式仍然成立。

  设

  $$g_{i,j}=\frac{y_i-y_j}{x_i-x_j}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (i>j)$$

  则上式可以表示为$g_{j,k}<X_i$

  我们来发掘以下$g_{j,k}$的性质。

  1. 当$g_{j,k}\leq X_i$时,由于随着$i$变大,$X_i$也变大,所以显然从$k$转移是永远不会比$j$好的,所以我们可以把$k$扔掉。

  2. 当$g_{i,j}\leq g_{j,k}$时,从$i$或者$k$转移至少有一个不比$j$差,所以可以把$j$扔掉。为什么??

    若$g_{i,j}\leq X_i$,显然$j$要被扔掉,根据第一个性质。

    若$g_{i,j}>X_i$,则$g_{j,k}>X_i$,那么显然$j$比$k$差,也得被扔掉。

  于是我们可以用一个单调队列来维护斜率的单调性。

  具体的:

  当情况1发生的时候让队首出队。

  在进队的时候,如果发生情况2,那么先让队尾出队,然后再进队。

  为了避免精度问题,我们可以把$x_i-x_j$乘上来。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1000005;
int n,q[N],head=1,tail=0;
LL a[N],b[N],X[N],sum[N],vsum[N],dp[N],x[N],y[N];
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%lld%lld%lld",&X[i],&b[i],&a[i]);
for (int i=1;i<=n;i++)
sum[i]=sum[i-1]+b[i],vsum[i]=vsum[i-1]+b[i]*X[i];
q[++tail]=0;
for (int i=1;i<=n;i++){
int j=q[head+1],k=q[head];
while (tail-head>0&&y[j]-y[k]<=(x[j]-x[k])*X[i])
head++,j=q[head+1],k=q[head];
j=k;
dp[i]=dp[j]+vsum[j]-vsum[i]+(sum[i]-sum[j])*X[i]+a[i];
x[i]=sum[i];
y[i]=dp[i]+vsum[i];
j=q[tail],k=q[tail-1];
while (tail-head>0&&(y[i]-y[j])*(x[j]-x[k])<=(y[j]-y[k])*(x[i]-x[j]))
tail--,j=q[tail],k=q[tail-1];
q[++tail]=i;
}
printf("%lld",dp[n]);
return 0;
}

  

BZOJ1096 [ZJOI2007]仓库建设 动态规划 斜率优化的更多相关文章

  1. BZOJ1096 ZJOI2007 仓库建设 【斜率优化DP】

    BZOJ1096 ZJOI2007 仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般 ...

  2. BZOJ1096 [ZJOI2007]仓库建设(斜率优化)

    题目背景 小B的班级数学学到多项式乘法了,于是小B给大家出了个问题:用编程序来解决多项式乘法的问题. 题目描述 L公司有N个工厂,由高到底分布在一座山上. 工厂1在山顶,工厂N在山脚. 由于这座山处于 ...

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

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5790  Solved: 2597[Submit][Status][Discuss] Descript ...

  4. 2018.09.07 bzoj1096: [ZJOI2007]仓库建设(斜率优化dp)

    传送门 斜率优化dp经典题. 令f[i]表示i这个地方修建仓库的最优值,那么答案就是f[n]. 用dis[i]表示i到1的距离,sump[i]表示1~i所有工厂的p之和,sum[i]表示1~i所有工厂 ...

  5. [BZOJ1096][ZJOI2007]仓库建设(斜率优化DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1096 分析: 假设1~10,如果在3 6 10建立仓库,那么当前建立仓库决策下的最优值 ...

  6. BZOJ 1096: [ZJOI2007]仓库建设 动态规划 + 斜率优化

      #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #defi ...

  7. 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3940  Solved: 1736 Description ...

  8. 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 ...

  9. 【洛谷】2120:[ZJOI2007]仓库建设【斜率优化DP】

    P2120 [ZJOI2007]仓库建设 题目背景 小B的班级数学学到多项式乘法了,于是小B给大家出了个问题:用编程序来解决多项式乘法的问题. 题目描述 L公司有N个工厂,由高到底分布在一座山上. 工 ...

随机推荐

  1. 前端 -----jQuery的事件绑定和解绑

    11-jQuery的事件绑定和解绑   1.绑定事件 语法: bind(type,data,fn) 描述:为每一个匹配元素的特定事件(像click)绑定一个事件处理器函数. 参数解释: type (S ...

  2. Maven多模块项目加载

      Maven多模块项目中如何让Spring运行时成功加载指定的子模块   将子模块pom加入到父模块pom的定义中,并继承父模块   在web.xml中配置加载子模块的Spring配置文件   在启 ...

  3. python-面向对象入门

    一.面向对象介绍 介绍面向对象之前,先来回顾一下以前学的面向过程的编程思想 面向过程编程: 核心是过程二字,过程指的是解决问题的步骤,即先干什么,再干什么后干什么,基于该思想编程就好比是在设计一条流水 ...

  4. 洛谷P3246 [HNOI2016]序列 [莫队]

    传送门 思路 看到可离线.无修改.区间询问,相信一定可以想到莫队. 然而,莫队怎么转移是个大问题. 考虑\([l,r]\rightarrow[l,r+1]\)时答案会怎样变化?(左端点变化时同理) \ ...

  5. html学习——基础分类总结

        1. html     超文本标记语言HyperText Markup Language.html文档基本结构: <!DOCTYPE html><head> <! ...

  6. Confluence 6 配置日志

    我们推荐你根据你的需求来配置你自己的 Confluence 日志.你可以有下面 2 种方法来修改你的日志: 通过 Confluence 管理员控制台进行配置 – 你的修改仅在本次修改有效,下次重启后将 ...

  7. Confluence 6 用户目录图例 - 和 Jira 连接到 Crowd

      上面的图:Confluence, JIRA 和其他应用程序连接到 Crowd 作为用户管理. https://www.cwiki.us/display/CONF6EN/User+Managemen ...

  8. iframe内容自适应高度

    一直觉得要用JS才能实现iframe高度的自适应,其实CSS也可以,而且实现的更好,只是需要给包裹iframe的DIV设置个高度,然后让irame高度设置成100%就可以自适应了. 完美版Iframe ...

  9. 分块入门(根据hzwer的博客。。)(右端点是r不是n。。)

    1.区间更新单点查询 #include <bits/stdc++.h> using namespace std; #define ll long long #define maxn 100 ...

  10. 配置webpack loader vue 报错:Module build failed: TypeError: this._init is not a function

    单文件组件 引入时报错 配置webpage.config.js中的vue 需要如下写法 { test: /\.vue/, loader: "vue-loader", } 之前写的l ...