斜率优化DP(转载)
转载自:https://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html
我们知道,有些DP方程可以转化成DP[i]=f[j]+x[i]的形式,其中f[j]中保存了只与j相关的量。这样的DP方程我们可以用单调队列进行优化,从而使得O(n^2)的复杂度降到O(n)。
可是并不是所有的方程都可以转化成上面的形式,举个例子:dp[i]=dp[j]+(x[i]-x[j])*(x[i]-x[j])。如果把右边的乘法化开的话,会得到x[i]*x[j]的项。这就没办法使得f[j]里只存在于j相关的量了。于是上面的单调队列优化方法就不好使了。
这里学习一种新的优化方法,叫做斜率优化,其实和凸包差不多,下面会解释。
举例子说明是最好的!HDU 3507,很适合的一个入门题。http://acm.hdu.edu.cn/showproblem.php?pid=3507
大概题意就是要输出N个数字a[N],输出的时候可以连续连续的输出,每连续输出一串,它的费用是 “这串数字和的平方加上一个常数M”。
我们设dp[i]表示输出到i的时候最少的花费,sum[i]表示从a[1]到a[i]的数字和。于是方程就是:
dp[i]=dp[j]+M+(sum[i]-sum[j])^2;
很显然这个是一个二维的。题目的数字有500000个,不用试了,二维铁定超时了。那我们就来试试斜率优化吧,看看是如何做到从O(n^2)复杂度降到O(n)的。
分析:
我们假设k<j<i。如果在j的时候决策要比在k的时候决策好,那么也是就是dp[j]+M+(sum[i]-sum[j])^2<dp[k]+M+(sum[i]-sum[k])^2。(因为是最小花费嘛,所以优就是小于)
两边移项一下,得到:(dp[j]+sum[j]^2-(dp[k]+sum[k]^2))/(2*(sum[j]-sum[k]))<sum[i]。我们把dp[j]-sum[j]^2看做是yj,把2*sum[j]看成是xj。
那么不就是yj-yk/xj-xk<sum[i]么? 左边是不是斜率的表示?
那么yj-yk/xj-xk<sum[i]说明了什么呢? 我们前面是不是假设j的决策比k的决策要好才得到这个表示的? 如果是的话,那么就说明g[j,k]=yj-jk/xj-xk<sum[i]代表这j的决策比k的决策要更优。
关键的来了:现在从左到右,还是设k<j<i,如果g[i,j]<g[j,k],那么j点便永远不可能成为最优解,可以直接将它踢出我们的最优解集。为什么呢?
我们假设g[i,j]<sum[i],那么就是说i点要比j点优,排除j点。
如果g[i,j]>=sum[i],那么j点此时是比i点要更优,但是同时g[j,k]>g[i,j]>sum[i]。这说明还有k点会比j点更优,同样排除j点。
排除多余的点,这便是一种优化!
接下来看看如何找最优解。
设k<j<i。
由于我们排除了g[i,j]<g[j,k]的情况,所以整个有效点集呈现一种上凸性质,即k j的斜率要大于j i的斜率。

这样,从左到右,斜率之间就是单调递减的了。当我们的最优解取得在j点的时候,那么k点不可能再取得比j点更优的解了,于是k点也可以排除。换句话说,j点之前的点全部不可能再比j点更优了,可以全部从解集中排除。
于是对于这题我们对于斜率优化做法可以总结如下:
1,用一个单调队列来维护解集。
2,假设队列中从头到尾已经有元素a b c。那么当d要入队的时候,我们维护队列的上凸性质,即如果g[d,c]<g[c,b],那么就将c点删除。直到找到g[d,x]>=g[x,y]为止,并将d点加入在该位置中。
3,求解时候,从队头开始,如果已有元素a b c,当i点要求解时,如果g[b,a]<sum[i],那么说明b点比a点更优,a点可以排除,于是a出队。最后dp[i]=getDp(q[head])。
以下代码是我自己敲了一遍
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int s[];
int dp[],q[];
int m,n;
int head,tail;
int getdp(int i,int j)
{
return dp[j]+m+(s[i]-s[j])*(s[i]-s[j]);
}
int getup(int j,int k)
{
return dp[j]+s[j]*s[j]-(dp[k]+s[k]*s[k]);
}
int getdown(int j,int k)
{
return *(s[j]-s[k]);
}
int main()
{
while(scanf("%d%d",&n,&m)==)
{
for(int i=; i<=n; i++)scanf("%d",&s[i]);
s[]=dp[]=;
for(int i=; i<=n; i++)s[i]+=s[i-];
head=,tail=;
q[tail++]=;
for(int i=; i<=n; i++)
{
while(head+<tail&&getup(q[head+],q[head])<=s[i]*getdown(q[head+],q[head]))
head++;
/* head+1,个比head 更优,所以直排除head,让head++,至于之前的head,谁管他呢?这么菜, 还有脸留着浪费时间?*/
dp[i]=getdp(i,q[head]);
while(head+<tail&&getup(i,q[tail-])*getdown(q[tail-],q[tail-])<= getup(q[tail-],q[tail-])*getdown(i,q[tail-]))
tail--;
/*说明 (tail-1 ,1)的决策比 (tail-2,~tail-1)更大,则说明,tail-1 是比tail-2更优的,
而i是比tail更优的则,tail可以被排除了。tail--*/
q[tail++]=i;
}
printf("%d\n",dp[n]);
}
return ;
}
斜率优化DP(转载)的更多相关文章
- bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)
题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...
- bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)
题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...
- [BZOJ3156]防御准备(斜率优化DP)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP
- 【BZOJ-1096】仓库建设 斜率优化DP
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3719 Solved: 1633[Submit][Stat ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
- BZOJ 3156: 防御准备 斜率优化DP
3156: 防御准备 Description Input 第一行为一个整数N表示战线的总长度. 第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai. Output 共一个整数,表示最小的战 ...
- HDU2829 Lawrence(斜率优化dp)
学了模板题之后上网搜下斜率优化dp的题目,然后就看到这道题,知道是斜率dp之后有思路就可以自己做不出来,要是不事先知道的话那就说不定了. 题意:给你n个数,一开始n个数相邻的数之间是被东西连着的,对于 ...
- HDU3507 Print Article(斜率优化dp)
前几天做多校,知道了这世界上存在dp的优化这样的说法,了解了四边形优化dp,所以今天顺带做一道典型的斜率优化,在百度打斜率优化dp,首先弹出来的就是下面这个网址:http://www.cnblogs. ...
- HDU 3507 Print Article(斜率优化DP)
题目链接 题意 : 一篇文章有n个单词,如果每行打印k个单词,那这行的花费是,问你怎么安排能够得到最小花费,输出最小花费. 思路 : 一开始想的简单了以为是背包,后来才知道是斜率优化DP,然后看了网上 ...
随机推荐
- OUC_Summer Training_ DIV2_#7 718
是18号做的题啦,现在才把报告补上是以前不重视报告的原因吧,不过现在真的很喜欢写报告,也希望能写一些有意义的东西出来. A - Dragons Time Limit:2000MS Memory ...
- 在HearthRanger中使用Silverfish
I'm new here and have never used this bot before. But a few days ago I tried it and I liked it :) I ...
- Trees Made to Order——Catalan数和递归
Trees Made to Order Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7155 Accepted: 40 ...
- 一百零四:CMS系统之修改邮箱界面
在base.css中加一个全局的css控制宽度 .form-container{ width: 300px;} 视图 class ResetEmailView(views.MethodView): d ...
- 部署Hadoop-3.0-高性能集群
一.Hadoop概述: Hadoop是一个由Apache基金会所开发的分布式系统基础架构.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储.Hadoop的框 ...
- 不知道AI这三点优势,你可能真的要被淘汰
不知道 AI 这三点优势,你可能真的要被淘汰 我们正处于飞速发展的数字化转型时期,这是由巨大的市场转变驱动的--即人工智能和机器学习. 同时,随着AI 和机器学习技术的普及,从中获益的不仅仅是大型企业 ...
- Delphi通过ADO读写数据库
ADO是一种程序对象,用于表示用户数据库中的数据结构和所包含的数据. ADO (ActiveX Data Objects,ActiveX数据对象)是Microsoft提出的应用程序接口(API)用以实 ...
- 前台请求响应json
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- 不可不知的JavaScript 之 JSON对象和JavaScript对象直接量
JSON对象和JS对象直接量 在工作当中,我们总是可以听到人说将数据转换为JSON对象,或者说把JSON对象转换为字符串之类的话,下面是关于JSON的具体说明. JSON对象并不是JavaScript ...
- svn clearup svn cleanup failed–previous operation has not finished; run cleanup if it was int错误的解决办法
今天svn提交,出现异常:svn cleanup failed–previous operation has not finished; run cleanup if it was interrupt ...