斜率优化dp


本来想直接肝这玩意的结果还是被忽悠着做了两道数论
现在整天浑浑噩噩无心学习甚至都不是太想颓废是不是药丸的表现
各位要知道我就是故意要打删除线并不是因为排版错乱
反正就是一个del标签嘛并不是什么大事的说
讲道理这一篇要不是写laTex我就直接用html写了

Emmmm划掉的原因是因为跟正题一点关系都没有啊

不让自己写摘要我写第一段凑摘要好咯

第一次写花花绿绿的blog感觉还是很新鲜的

你看看我到了正文部分还划不划啊(该划的还是划╭(╯^╰)╮)

其实文章里有彩蛋比如这里 被你发现了OvO 哈哈

据说找到了所有的彩蛋能获得一些奖励(但很不幸这是假的

不过laTex公式也可以带颜色这真的是太棒啦

这一段对的如此不整齐的原因可能是为了逼死强迫症

明明是懒得把字数扣成一样的非要找这么个冠冕堂皇的借口么

上次我们说过

\[f[i]=max\{f[j]+x[j]\}(j\in[1,i))
\]

这样的方程的优化(变量记录)和

\[f[i]=max\{f[j]+x[j]\} (j\in[i-m,i))
\]

这样的方程的优化(单调队列), 但是如果遇到

\[f[i]=max\{f[j]+g(i,j)\} (j\in[1,i)
\]

这样的方程, 就不会处理了... 这也就是今天要讲的斜率优化dp.

对于这种方程, 我们考虑将这个式子化成\(y\)=\(k\)\(x\)+\(b\)的形式, 其中\(y\)和\(x\)是只和\(j\)相关的式子, \(k\)是和\(i\)相关的式子, \(b\)是\(f[i]\)和其他什么常数, 然后根据类似于线性规划的知识维护一定的单调性来优化转移.

光这么讲也没什么意思嘛(鬼能看懂咯), 我们看例题. 其实就是bzoj1010 第一页就有 传送门在这里~

状态转移方程比较显然: 令\(f[i]\)表示装前\(i\)个东西的最小花费, \(sum[i]\)表示\(C_i\)的前缀和, 则

\[f[i]=min\{f[j]+(sum[i]-sum[j]+i-j-1-L)^2\}
\]

这样我们已经可以\(O(n^2)\)做了, 不过并没有给部分分, 不知道能得几分, 反正\(n\leq5W\)想A掉是不可能的.这辈子都是不可能的. dp优化以后跑得又快, 又可以装逼, 我超喜欢优化的!

所以很明显需要优化. 那么就是说要化式子.我讨厌化式子!!!

为了方便, 我们令\(s[i]=sum[i]+i,C=L+1\), 那么

\[f[i]=f[j]+(s[i]-s[j]-C)^2=f[j]+(s[i]-C)^2-2(s[i]-C)*s[j]+s[j]^2
\]

然后移项, 得到

\(f[j]+s[j]^2\)=\(2(s[i]-C)\)*\(s[j]\)+\(f[i]-(s[i]-C)^2\)

这样就出现了\(y\)=\(k\)\(x+\)\(b\)的形式. 根据线性规划一类的知识, 我们要在可行域中最小化\(f[i]\), 就是要最小化\(截距b\). 话说化带颜色的式子的时候的laTex也是挺好看的..

那么怎么最小化截距呢? 我们画个图. 画的很丑大家轻喷...



首先很明显我们dp的时候求好\(t\)的状态可以存在一个点\((x,\)\(y\)\()\)里面, 即\((s[t],\)\(f[t]-s[t]^2\)\()\). 这样我们每次就拿一条斜率为\(2(s[i]-C)\)的直线去里面找截距的最小值就行了. 但这样还是\(O(n^2)\)的, 因为我们没有充分利用单调性来去掉那些根本不可能优的点.

Emmmm其实这张图画得更草率OvO

我们可以看到 如果将要插入的点是红色的, 那么无论斜率怎样, 它都不会比已经加入过的点优(截距更小), 我们就不需要考虑红色点了, 但是蓝色的点则是可能更优的, 那么我们就要保留蓝色点.

其实这里要证明决策单调性什么的 但画图就显得很直观 显然成立我们就不证了(明明是因为懒←_←

经过若干个点的验证, 我们发现, 可能更优的点都集中在下凸壳上!

那么我们维护下凸壳就好了. 这样的话转移的复杂度似乎从\(O(n)\)降到了\(O(H)\), 但似乎还是该怎么过不去就怎么过不去.

所以继续考虑, 为什么转移的时候非要遍历所有点呢?

我们惊奇地发现, 这个题有一个性质, 就是斜率\(k=2(s[i]-C)\)是递增的, 所以吧,



我们枚举下一个斜率的时候, 可以发现, 如果这个点与下一个点的连线的斜率比枚举的斜率小(前两个点), 那么截距就会比下一个点大, 而且由于斜率递增, 所以差距会越来越大, 那这个点我们就可以不要了. 所以我们就可以看出可以用一个单调队列来维护这个凸壳, 每次先把队首不合法的弹出, 然后取队首转移即可. 其实这里关于斜率的讨论应该是要化一波覆盖的式子的, 但是也是由图显然, 而且做半平面交的时候化过, 这里就不化了(显然还是因为懒←_←

这样的话转移的时间复杂度就从\(O(H)\)降到了\(O(1)\), 总复杂度也就降到了\(O(n)\)的水平, 就可以非常愉快的通过此题啦~ 所以不是很懂一个正解\(O(n)\)的题目给个\(n\leq5W\)的数据范围是几个意思...

惊奇地发现自己调了一个晚上的原因竟然是化式子移项正负号反了??? 应该打回小学重造.

本来想用叉积结果化出来的式子太臃肿 我当时还不知道自己式子化错了然后不好调就删掉改成斜率了.

非常不喜欢这样损精度的方式但其实都是整数所以还好, 但是后来发现式子化错了之后懒得改就这么写下去了...

有一点就是5W*1e7要开long long.. 其实代码非常简单... 就这么几行你还调了一晚上←_←

#include <cmath>
#include <cstdio>
const int N=5e4+5;
typedef long long LL;
inline int gn(int a=0,char c=0){
for(;c<'0'||c>'9';c=getchar());
for(;c>47&&c<58;c=getchar())a=a*10+c-48;return a;
}
LL s[N],f[N];int q[N],h=0,t=0,n,l;
double slope(int x,int y){return 1.0*(f[x]+s[x]*s[x]-f[y]-s[y]*s[y])/(s[x]-s[y]);}
int main(){
n=gn(),l=gn()+1;
for(int i=1;i<=n;++i) s[i]=s[i-1]+gn()+1;
for(int i=1;i<=n;++i){
while(h<t&&slope(q[h],q[h+1])<=2*(s[i]-l)) ++h;
f[i]=f[q[h]]+(s[i]-s[q[h]]-l)*(s[i]-s[q[h]]-l);
while(h<t&&slope(q[t],q[t-1])>=slope(i,q[t])) --t;
q[++t]=i;
} printf("%lld",f[n]);
}

我觉得代码写的非常清楚了 就这样吧...

怎么样,找到所有透明的字了嘛?? 哈哈哈~

【笔记篇】斜率优化dp(一) HNOI2008玩具装箱的更多相关文章

  1. 【斜率优化】BZOJ1010 [HNOI2008]玩具装箱toy

    [题目大意] P教授有编号为1...N的N件玩具,第i件玩具长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的.如果将第i件玩具到第j个玩具放到一 个容器中,那么容器的长度将为 x ...

  2. 「学习笔记」斜率优化dp

    目录 算法 例题 任务安排 题意 思路 代码 [SDOI2012]任务安排 题意 思路 代码 任务安排 再改 题意 思路 练习题 [HNOI2008]玩具装箱 思路 代码 [APIO2010]特别行动 ...

  3. 一本通提高篇——斜率优化DP

    斜率优化DP:DP的一种优化形式,主要用于优化如下形式的DP f[i]=f[j]+x[i]*x[j]+... 学习可以参考下面的博客: https://www.cnblogs.com/Xing-Lin ...

  4. 学习笔记:斜率优化DP

    作为数学渣,先复习一下已知两点\((x_1, y_1)\), \((x_2, y_2)\),怎么求过两点的一次函数的斜率... 待定系数法代入 \(y = kx + b\) 有: \(x_1k + b ...

  5. hdu3507 斜率优化学习笔记(斜率优化+dp)

    QWQ菜的真实. 首先来看这个题. 很显然能得到一个朴素的\(dp\)柿子 \[dp[i]=max(dp[i],dp[j]+(sum[i]-sum[j])^2) \] 但是因为\(n\le 50000 ...

  6. 斜率优化dp学习笔记 洛谷P3915[HNOI2008]玩具装箱toy

    本文为原创??? 作者写这篇文章的时候刚刚初一毕业…… 如有错误请各位大佬指正 从例题入手 洛谷P3915[HNOI2008]玩具装箱toy Step0:读题 Q:暴力? 如果您学习过dp 不难推出d ...

  7. BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9812  Solved: 3978[Submit][St ...

  8. BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP

    1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...

  9. bzoj 1010 [HNOI2008]玩具装箱toy(DP的斜率优化)

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 7874  Solved: 3047[Submit][St ...

随机推荐

  1. Java【并发】面试题

    精尽 Java[并发]面试题 以下面试题,基于网络整理,和自己编辑.具体参考的文章,会在文末给出所有的链接. 如果胖友有自己的疑问,欢迎在星球提问,我们一起整理吊吊的 Java[并发]面试题的大保健. ...

  2. Codeforces 1176B - Merge it!

    题目链接:http://codeforces.com/problemset/problem/1176/B 题意:给定序列,任意俩个元素可以相加成一个元素,求序列元素能被3整除的最大数量. 思路: 对于 ...

  3. jQuery validate验证隐藏表单(hidden)域

    validate很不错的一个jQuery表单验证插件.升级到了1.9版的后,发现隐藏表单域验证全部失效,特别是在jquery.ui.tabs.min.js构造的Tabs里的验证!网上一搜,也没查到是怎 ...

  4. 记录阿里云ECS搭建Wordpress(Centos7+LAMP)

    占位 改变wordpress文件夹属主属组 cd /var/www/html chown -R apache:apache wordpress <VirtualHost *:> Docum ...

  5. 如何删除github里的项目

    1.登录github网站后,就会看到如下画面,在头像下面有个你的项目资源这一栏,假如我要删除名为“hhh”的项目,现在鼠标点进这个项目里面 2.进去后点setting 点进去后,默认是选择了OPtio ...

  6. 微信小程序之评分页面

    首先给大家看看做好的效果图: 一.接下来我们说一下评分这个功能: 实际上就是一个简单的js,首先我们遍历出小星星,此时默认给的五星好评,在给他们一个点击事件,当点击时,我们获取到当前点击的是第几颗:代 ...

  7. 【第十周读书笔记】读node入门,一本全面的node.js教程

    我学到了路由的定义,路由就是解析URL然后转到相应的执行程序. 我们要为路由提供请求的URL和其他需要的GET及POST参数,随后路由需要根据这些数据来执行相应的代码(这里“代码”对应整个应用的第三部 ...

  8. GarsiaWachs算法

    解决石子问题: 题目描述如下: 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安排怎样的合并顺序,能够使得 ...

  9. Job 和 Cronjob 的使用

    Job负责处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束.而CronJob则就是在Job上加上了时间调度. Job 我们用Job这个资源对象来创建一个任务,我们定一个Job来 ...

  10. python编程学习day04

    1.函数名是变量名 “=”是内存指向,等号赋值操作,内存指向操作 变量——可赋值,可作为列表元素 函数名可以作为返回值返回 函数名可作为参数传递 2.闭包 内层函数使用了外层函数的变量 作用:可以让一 ...