洛谷 P3195 [HNOI2008] 玩具装箱
链接:
题意:
给出 \(n\) 个物品及其权值 \(c\),连续的物品可以放进一个容器,如果将 \(i\sim j\) 的物品放进一个容器,产生的费用是 \(\left(j-i+\sum\limits_{k=i}^jc_k-L\right)^2\),其中 \(L\) 是一个给出的常数,现在需要把所有物品都放进容器,请你最小化总费用。
分析:
这是一道非常经典的好题,适合练习单调队列优化和斜率优化dp。
我们设 \(sum[i]\) 表示物品权值的前缀和,\(dp[i]\) 表示前 \(i\) 个物品的最小总费用,那么有 \(O(n)\) 转移:
\]
我们将后面的式子化一下,把与 \(i\) 有关的和与 \(j\) 有关的拉出来,常数项随意丢进里面,
\]
令 \(A(i)=i+sum[i],B(j)=j+sum[j]+L+1\)
\]
我们发现 \(A(i)\) 和 \(B(j)\) 都是已知的,而 \(A(i)\) 只与当前位置有关,\(B(j)\) 只与之前的位置有关,可以视为决策。
由于存在 \(A(i)B(j)\) 这种既与当前位置有关,又与决策有关的东西,于是我们尝试将与决策有关的东西单独分离出来。我们对这个式子进行变换:
\]
可以将其视为一条斜率为 \(2A(i)\) 的直线,经过定点 \((B(j),dp[j]+B(j)^2)\),截距为 \(dp[i]-A(i)^2\)。
我们成功将决策的信息与整合到了一个点上!现在需要做的就是选择一个最优的点,使得一条斜率一定的直线经过这个点时截距最小。
图片摘自洛谷博客

我们通过观察可以发现,可能作为最优决策的点构成了一个下凸包(这在其他题目中可能不同),且对于一条斜率为 \(k\) 的直线,最优决策点是第一个满足 \(slope(x,x+1)\geq k\) 的点。(\(slope\) 表示斜率)
用单调队列维护凸包。同时注意到每次询问的斜率 \(2A(i)\) 也是单调增的,于是对于找到最优决策点还可以用单调队列优化。
注意到一个细节是要 "插入第0个点" 的信息,否则无法将 \(1\sim i\) 放进一个容器。
算法:
单调队列维护下凸包,同时维护最优决策点,然后每次根据最优决策的信息得到 \(dp[i]\),继续维护凸包即可。时间复杂度 \(O(n)\)。
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define in read()
inline int read(){
int p=0,f=1;
char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){p=p*10+c-'0';c=getchar();}
return p*f;
}
const int N=5e4+5;
#define A(x) (x+sum[x])
#define B(x) (x+sum[x]+1+L)
#define X(x) (B(x))
#define Y(x) (dp[x]+B(x)*B(x))
#define dx(x,y) (X(x)-X(y))
#define dy(x,y) (Y(x)-Y(y))
#define slope(x,y)(double(dy(x,y))/dx(x,y))
int n,L,sum[N],dp[N],q[N],qi=1,qn=1;
signed main(){
n=in,L=in;
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+in;
for(int i=1;i<=n;i++){
while(qi<qn&&slope(q[qi+1],q[qi])<2*A(i))qi++;
dp[i]=dp[q[qi]]+(A(i)-B(q[qi]))*(A(i)-B(q[qi]));
while(qn>qi&&slope(q[qn],q[qn-1])>slope(i,q[qn-1]))qn--;
q[++qn]=i;
}
cout<<dp[n];
return 0;
}
题外话:
真的是一道极好的斜优入门题。
洛谷 P3195 [HNOI2008] 玩具装箱的更多相关文章
- 洛谷P3195 [HNOI2008] 玩具装箱 [DP,斜率优化,单调队列优化]
题目传送门 题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N ...
- 洛谷P3195 [HNOI2008]玩具装箱TOY——斜率优化DP
题目:https://www.luogu.org/problemnew/show/P3195 第一次用斜率优化...其实还是有点云里雾里的: 网上的题解都很详细,我的理解就是通过把式子变形,假定一个最 ...
- 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)
题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...
- [洛谷P3195][HNOI2008]玩具装箱TOY
题目大意:有n个物体,大小为$c_i$.把第i个到第j个放到一起,容器的长度为$x=j-i+\sum\limits_{k-i}^{j} c_k$,若长度为x,费用为$(x-L)^2$.费用最小. 题解 ...
- 洛谷P3195 [HNOI2008]玩具装箱TOY 斜率优化
Code: #include<cstdio> #include<algorithm> using namespace std; const int maxn = 100000 ...
- 洛谷 P3195 [HNOI2008]玩具装箱TOY
题意简述 有n个物体,第i个长度为ci 将n个物体分为若干组,每组必须连续 如果把i到j的物品分到一组,则该组长度为 \( j - i + \sum\limits_{k = i}^{j}ck \) 求 ...
- 斜率优化dp学习笔记 洛谷P3915[HNOI2008]玩具装箱toy
本文为原创??? 作者写这篇文章的时候刚刚初一毕业…… 如有错误请各位大佬指正 从例题入手 洛谷P3915[HNOI2008]玩具装箱toy Step0:读题 Q:暴力? 如果您学习过dp 不难推出d ...
- 洛谷3195(HNOI2008)玩具装箱
题目:https://www.luogu.org/problemnew/show/P3195 自己做斜率优化的第一道题. 推成斜率优化的样子很重要. 斜率优化的样子就是从 j 中求 i 的话,关系式里 ...
- 洛谷3195 [HNOI2008]玩具装箱TOY(斜率优化+dp)
qwq斜率优化好题 第一步还是考虑最朴素的\(dp\) \[dp=dp[j]+(i-j-1+sum[i]-sum[j])^2 \] 设\(f[i]=sum[i]+i\) 那么考虑将上述柿子变成$$dp ...
随机推荐
- 5-21python数据类型
一.字符串,是不可变数据类型,所有字符串的方法都不会修改字符串的值,使用字符串的方法后都是生成了一个新的字符串.就因为字符串是不可变变量! 字符串的方法 1. strip(),默认去空格,但是当()中 ...
- php各个版本curl上传文件的兼容实现
// 以POST方式提交数据 public function post_data($url, $param, $is_file = false, $return_array = true) { ... ...
- (未完)Java集合框架梳理(基于JDK1.8)
Java集合类主要由两个接口Collection和Map派生出来的,Collection派生出了三个子接口:List.Set.Queue(Java5新增的队列),因此Java集合大致也可分成List. ...
- python math详解(1)
python math详解(1) 一.导入 python要调用math要进行导入 import math 二.返回值 math包里有一些值 比如 math.pi 返回pi的值 约为3.14 math. ...
- Java实现导入Excel文件
一.配置文件名称.路径.内容: <bean id="multipartResolver" class="org.springframework.web.multip ...
- JMeter多个线程组的使用说明
Run Thread Groups consecutively (i.e one at a time),即独立运行每个线程组(例如在一个组运行结束后启动下一个) https://help.aliyun ...
- centos7 发送邮件
yum install sendmail mailx sharutils mutt libreport-plugin-mailx -y yum update libreport-plugin-mail ...
- 【转载】在Windows终端中显示UTF-8字符
一直苦恼于如何在Windows终端中显示UTF-8字符的问题.比如,在MySQL命令行下,如果数据库的编码是UTF-8,那么,在查询数据库的时候,里面的中文都会变成乱码.今天半无意的搜索了一下,结果发 ...
- 关于Redis的十个高频面试问题
文件来自大神的分析,小弟引用.希望更多的资源能被更多的人分享到!!! 一.Redis有哪些数据结构? 字符串String.字典Hash.列表List.集合Set.有序集合SortedSet. 如果你是 ...
- 鸿蒙内核源码分析(字符设备篇) | 字节为单位读写的设备 | 百篇博客分析OpenHarmony源码 | v67.01
百篇博客系列篇.本篇为: v67.xx 鸿蒙内核源码分析(字符设备篇) | 字节为单位读写的设备 | 51.c.h.o 文件系统相关篇为: v62.xx 鸿蒙内核源码分析(文件概念篇) | 为什么说一 ...