传送门

文章目录

  • 前言
  • 解析
  • 代码

前言

斜率优化dp,就是利用斜率优化的dp

(逃)

解析

第一道斜优的题
分析题目
设sumisum_isumi​为1-i的c的前缀和
容易写出dp转移式:
dpi=min(dpj+(sumi−sumj+i−j−1−L)2)dp_i=min(dp_j+(sum_i-sum_j+i-j-1-L)^2)dpi​=min(dpj​+(sumi​−sumj​+i−j−1−L)2)

但是平方转移会T掉
考虑优化
设:
ai=sumi+ia_i=sum_i+iai​=sumi​+i
bi=sumi+i+1+Lb_i=sum_i+i+1+Lbi​=sumi​+i+1+L
注意到对于固定的 i,a和b都是可求的定值
那么上面的dp,就可以写成:
dpi=min(dpj+(ai−bj)2)dp_i=min(dp_j+(a_i-b_j)^2)dpi​=min(dpj​+(ai​−bj​)2)
把平方拆开:
dpi=min(dpj+ai2+bj2−2∗ai∗bj)dp_i=min(dp_j+a_i^2+b_j^2-2*a_i*b_j)dpi​=min(dpj​+ai2​+bj2​−2∗ai​∗bj​)
为了转移优化,我们需要移一下项:
2∗ai∗bj+dpi−ai2=dpj+bj22*a_i*b_j+dp_i-a_i^2=dp_j+b_j^22∗ai​∗bj​+dpi​−ai2​=dpj​+bj2​

上面那个式子可以看成一个以bjb_jbj​为未知数,斜率为2∗ai2*a_i2∗ai​,且经过(bj,dpj+bj2)(b_j,dp_j+b_j^2)(bj​,dpj​+bj2​)的一次函数
没明白?这么看:
f(x)=2∗ai∗x+dpi−ai2f(x)=2*a_i*x+dp_i-a_i^2f(x)=2∗ai​∗x+dpi​−ai2​
f(bj)=dpj+bj2f(b_j)=dp_j+b_j^2f(bj​)=dpj​+bj2​
dpidp_idpi​就是这个函数与y轴的截距加上aia_iai​的平方,因此我们实际上就是要使函数在y轴上的截距最小
有了这个函数之后,我们就可以开始尝试优化了

对于每一个新的要求的dp[i],其直线对应的斜率是固定的
我们维护一个可以作为转移点的队列,其中的决策点对应的点对(b[x],dp[x]+b[x]^2)形成一个凸包的结构

由于随着 i 的增大,其直线的斜率(2∗ai2*a_i2∗ai​)单调递增,所以位于凸包上方的点是一定不会作为最优决策点的
若记A、B两点之间的斜率为slope(A、B)
不难看出,要使其这条直线的y轴截距最小,我们应该找到**第一个
slope(P[j],P[j+1])>2∗aislope(P[j],P[j+1])>2*a~i~slope(P[j],P[j+1])>2∗a i  的位置
而且由于斜率单调递增,Pj左侧的点以后一定不会再被选到了
所以我们可以用一个单调队列来维护
时间复杂度降为O(n)

代码

#include<bits/stdc++.h>
#define I register int
using namespace std;
#define ll long long
const int N=5e4+10;
ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;
}
int n;
ll sum[N],c[N],a[N],b[N],l,dp[N];
struct pos{ll x,y;int pl;
};
pos q[N];
int st,ed;
double slope(pos u,pos v){return 1.0*(v.y-u.y)/(v.x-u.x);
}
int main(){//  freopen("a.in","r",stdin);
//  freopen("a.out","w",stdout);n=read();l=read();for(int i=1;i<=n;i++){//printf("ok i=%d\n",i);c[i]=read();sum[i]=sum[i-1]+c[i];a[i]=sum[i]+i;b[i]=sum[i]+i+l+1;}b[0]=l+1;st=ed=1;q[1]={b[0],b[0]*b[0],0};for(int i=1;i<=n;i++){ll k=2*a[i];while(st<ed&&slope(q[st],q[st+1])<k) st++;ll x=q[st].x,y=q[st].y;int pl=q[st].pl;dp[i]=y+a[i]*a[i]-2*a[i]*b[pl];//printf("i=%d st=%lld dp=%lld k=%lld\n  ",i,q[st].pl,dp[i],k);//for(int i=st;i<=ed;i++) printf("%d:(%lld %lld %lld)  ",i,q[i].x,q[i].y,q[i].pl);//printf("\n\n");pos now=(pos){b[i],dp[i]+b[i]*b[i],i};while(st<ed&&slope(q[ed-1],q[ed])>slope(q[ed-1],now)){ed--;// printf("ou2!\n");}q[++ed]=now;}printf("%lld",(long long)dp[n]);return 0;
}
/*
6 10
5
8
5
10
19
1
*/

YBTOJ洛谷P3195:玩具装箱(斜率优化dp)相关推荐

  1. BZOJ1010玩具装箱 - 斜率优化dp

    传送门 题目分析: 设\(f[i]\)表示装前i个玩具的花费. 列出转移方程:\[f[i] = max\{f[j] + ((i - (j + 1)) + sum[i] - sum[j] - L))^2 ...

  2. 洛谷 P3195 [HNOI2008]玩具装箱 —— 斜率优化

    This way 题意: 题解: 洛谷的题解就写的蛮好,首先对于斜率优化,先将它的转移方程写出来,然后对于只包含i的设为A,只包含j的设为B,然后对于含有A和B的项就是二元一次方程中的k和x 这个就可 ...

  3. 洛谷P3195 [HNOI2008]玩具装箱TOY——斜率优化DP

    题目:https://www.luogu.org/problemnew/show/P3195 第一次用斜率优化...其实还是有点云里雾里的: 网上的题解都很详细,我的理解就是通过把式子变形,假定一个最 ...

  4. bzoj1010[HNOI2008]玩具装箱toy 斜率优化dp

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 11893  Solved: 5061 [Submit] ...

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

    Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...

  6. 【洛谷3648】[APIO2014] 序列分割(斜率优化DP)

    点此看题面 大致题意: 你可以对一个序列进行\(k\)次分割,每次得分为两个块元素和的乘积,求总得分的最大值. 区间\(DPor\)斜率优化\(DP\) 这题目第一眼看上去感觉很明显是区间\(DP\) ...

  7. 【bzoj1010】玩具装箱toy——斜率优化dp

    题目链接 第一道自己推的斜率优化dp>< 首先要明确一点:装进同一个容器的toys一定要是连着的几个(否则的话可以直接贪心)-->之前理解错题意WA了一次...... 用sum[i] ...

  8. 【BZOJ1010】【codevs1319】玩具装箱,斜率优化DP

    传送门1 传送门2 写在前面:好像double要比long long快? 思路:想拿来练手的斜率优化DP,却忘记了一些基本原则,好坑 基本的DP转移 f[i]=min(f[j]+(sum[i]−sum ...

  9. 洛谷 P1563 玩具谜题

    这里给出题目的链接洛谷 P1563 玩具谜题 分析题目,很明显可以知道人物可以用数字来表示,将人物的名字单独存在一个数组里面,获取最终人物对应的数字后,即可输出人物的名称,即这道题的答案. 这道题可以 ...

最新文章

  1. 数制系统之间的转换总结(各进制的转换)
  2. 非整数倍数数据位宽转换8to12
  3. matlab the installer cannot read,MATLAB安装 The installer cannot read the mwinstall.dll… | 学步园...
  4. CentOS7.0 安装 tomcat-9.0
  5. 【课题总结】OpenCV 抠图项目实战(12)源程序代码
  6. 麦咭智能机器人宣传片_【头脑风暴】移动机器人能够撬动上亿线下流量,挖掘市场增量吗?...
  7. 总结下2018年,我们归纳了几种将对智能安防产生影响的技术发展趋势
  8. 《乔布斯传.神一样的传奇》读后感
  9. 鸢尾花数据集的可视化
  10. fcm算法matlab实现,fcm算法matlab
  11. 哈佛大学公开课-幸福课-个人笔记
  12. 如何用burpsuite和手机模拟器给apk抓包
  13. android 怎么选择audio hal
  14. getAddrInfo与DNS域名解析与ping
  15. Spring Boot使用方法小札(3):应用启动后做一些事
  16. elementUI 表格合并单元格-多层级-合并行
  17. 汇编语言中间接寻址(间接操作数)与变址寻址(变址操作数)的区别
  18. Linux之父-林纳斯 配置命令基操
  19. Python爬虫之scrapy框架360全网图片爬取
  20. 【004 关键字】extern “C“的作用是什么?

热门文章

  1. sklearn集合算法预测泰坦尼克号幸存者
  2. data:text/html firefox钓鱼,JS DataURL 整理(一)
  3. android listview添加数据_Android面经分享,失业两个月,五一节前拿到offer
  4. oracle 大页配置,【Oracle】Oracle如何开启大页
  5. java使用zmodem_SecureCRT 中使用zmodem和Linux服务器交换文件
  6. matlab提示未定义wc,WooCommerce 教程:修复致命错误调用未定义的函数wc_get_order() - WooCommerce 微站...
  7. 怎样安装php52-71,CentOS如何安装PHP5和PHP7
  8. mysql的外键_mysql如何查看外键
  9. python反射、闭包、装饰器_python之闭包、装饰器、生成器、反射
  10. android中的帧动画,[Android开发] Android中的帧动画