YBTOJ洛谷P3195:玩具装箱(斜率优化dp)
传送门
文章目录
- 前言
- 解析
- 代码
前言
斜率优化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)相关推荐
- BZOJ1010玩具装箱 - 斜率优化dp
传送门 题目分析: 设\(f[i]\)表示装前i个玩具的花费. 列出转移方程:\[f[i] = max\{f[j] + ((i - (j + 1)) + sum[i] - sum[j] - L))^2 ...
- 洛谷 P3195 [HNOI2008]玩具装箱 —— 斜率优化
This way 题意: 题解: 洛谷的题解就写的蛮好,首先对于斜率优化,先将它的转移方程写出来,然后对于只包含i的设为A,只包含j的设为B,然后对于含有A和B的项就是二元一次方程中的k和x 这个就可 ...
- 洛谷P3195 [HNOI2008]玩具装箱TOY——斜率优化DP
题目:https://www.luogu.org/problemnew/show/P3195 第一次用斜率优化...其实还是有点云里雾里的: 网上的题解都很详细,我的理解就是通过把式子变形,假定一个最 ...
- bzoj1010[HNOI2008]玩具装箱toy 斜率优化dp
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MB Submit: 11893 Solved: 5061 [Submit] ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化dp
Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...
- 【洛谷3648】[APIO2014] 序列分割(斜率优化DP)
点此看题面 大致题意: 你可以对一个序列进行\(k\)次分割,每次得分为两个块元素和的乘积,求总得分的最大值. 区间\(DPor\)斜率优化\(DP\) 这题目第一眼看上去感觉很明显是区间\(DP\) ...
- 【bzoj1010】玩具装箱toy——斜率优化dp
题目链接 第一道自己推的斜率优化dp>< 首先要明确一点:装进同一个容器的toys一定要是连着的几个(否则的话可以直接贪心)-->之前理解错题意WA了一次...... 用sum[i] ...
- 【BZOJ1010】【codevs1319】玩具装箱,斜率优化DP
传送门1 传送门2 写在前面:好像double要比long long快? 思路:想拿来练手的斜率优化DP,却忘记了一些基本原则,好坑 基本的DP转移 f[i]=min(f[j]+(sum[i]−sum ...
- 洛谷 P1563 玩具谜题
这里给出题目的链接洛谷 P1563 玩具谜题 分析题目,很明显可以知道人物可以用数字来表示,将人物的名字单独存在一个数组里面,获取最终人物对应的数字后,即可输出人物的名称,即这道题的答案. 这道题可以 ...
最新文章
- 数制系统之间的转换总结(各进制的转换)
- 非整数倍数数据位宽转换8to12
- matlab the installer cannot read,MATLAB安装 The installer cannot read the mwinstall.dll… | 学步园...
- CentOS7.0 安装 tomcat-9.0
- 【课题总结】OpenCV 抠图项目实战(12)源程序代码
- 麦咭智能机器人宣传片_【头脑风暴】移动机器人能够撬动上亿线下流量,挖掘市场增量吗?...
- 总结下2018年,我们归纳了几种将对智能安防产生影响的技术发展趋势
- 《乔布斯传.神一样的传奇》读后感
- 鸢尾花数据集的可视化
- fcm算法matlab实现,fcm算法matlab
- 哈佛大学公开课-幸福课-个人笔记
- 如何用burpsuite和手机模拟器给apk抓包
- android 怎么选择audio hal
- getAddrInfo与DNS域名解析与ping
- Spring Boot使用方法小札(3):应用启动后做一些事
- elementUI 表格合并单元格-多层级-合并行
- 汇编语言中间接寻址(间接操作数)与变址寻址(变址操作数)的区别
- Linux之父-林纳斯 配置命令基操
- Python爬虫之scrapy框架360全网图片爬取
- 【004 关键字】extern “C“的作用是什么?
热门文章
- sklearn集合算法预测泰坦尼克号幸存者
- data:text/html firefox钓鱼,JS DataURL 整理(一)
- android listview添加数据_Android面经分享,失业两个月,五一节前拿到offer
- oracle 大页配置,【Oracle】Oracle如何开启大页
- java使用zmodem_SecureCRT 中使用zmodem和Linux服务器交换文件
- matlab提示未定义wc,WooCommerce 教程:修复致命错误调用未定义的函数wc_get_order() - WooCommerce 微站...
- 怎样安装php52-71,CentOS如何安装PHP5和PHP7
- mysql的外键_mysql如何查看外键
- python反射、闭包、装饰器_python之闭包、装饰器、生成器、反射
- android中的帧动画,[Android开发] Android中的帧动画