洛谷 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 ...
随机推荐
- Linux 文本相关命令(1)
Linux 文本相关命令(1) 前言 最近线上环境(Windows Server)出现了一些问题,需要分析一下日志.感觉 Windows 下缺少了一些 Linux 系统中的小工具,像在这波操作中用到的 ...
- 个人作业——CVPR顶会论文爬取
main.py #保存单个界面数据 def getInfo(url): # url='https://openaccess.thecvf.com/WACV2021' header={ 'User-Ag ...
- PTA 面向对象程序设计6-2 统计数字
对于给定的一个字符串,统计其中数字字符出现的次数. 类和函数接口定义: 设计一个类Solution,其中包含一个成员函数count_digits,其功能是统计传入的string类型参数中数字字符的个数 ...
- easyx小游戏
#include "stdafx.h" int main(){ srand(time(NULL)); initgraph(640,480); int user_x=20,user_ ...
- 【PHP数据结构】顺序表(数组)的相关逻辑操作
在定义好了物理结构,也就是存储结构之后,我们就需要对这个存储结构进行一系列的逻辑操作.在这里,我们就从顺序表入手,因为这个结构非常简单,就是我们最常用的数组.那么针对数组,我们通常都会有哪些操作呢? ...
- java中的swing设计界面时怎么加上背景图片。而不覆盖其他控件?
通过以下方式设置下背景就可以了: import java.awt.Container; import javax.swing.ImageIcon; import javax.swing.JFrame; ...
- shell 一些常用命令
一般自己虚拟机新安装的centos才需要此配置 setenforce 是Linux的selinux防火墙配置命令 执行setenforce 0 表示关闭selinux防火墙. getenforce 查 ...
- 鸿蒙内核源码分析(中断概念篇) | 海公公的日常工作 | 百篇博客分析OpenHarmony源码 | v43.02
百篇博客系列篇.本篇为: v43.xx 鸿蒙内核源码分析(中断概念篇) | 海公公的日常工作 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CPU在哪里 ...
- P4717-[模板]快速莫比乌斯/沃尔什变换(FMT/FWT)
正题 题目链接:https://www.luogu.com.cn/problem/P4717 题目大意 给出两个长度为\(2^n\)的数列\(A,B\)求 \[C_{n}=\sum_{i\ or\ j ...
- CF1446F-Line Distance【计算几何,树状数组,二分】
正题 题目链接:https://www.luogu.com.cn/problem/CF1446F 题目大意 给出\(n\)个点,求所有点对构成的直线中与原点距离第\(k\)小的距离 \(2\leq n ...