链接:

P3195


题意:

给出 \(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)\) 转移:

\[dp[i]=\min \left(dp[j]+(i-(j+1)+sum[i]-sum[j]-L)^2\right)
\]

我们将后面的式子化一下,把与 \(i\) 有关的和与 \(j\) 有关的拉出来,常数项随意丢进里面,

\[dp[i]=dp[j]+( (i+sum[i])-(j+sum[j]+L+1) )^2
\]

令 \(A(i)=i+sum[i],B(j)=j+sum[j]+L+1\)

\[dp[i]=dp[j]+A(i)^2-2A(i)B(j)+B(j)^2
\]

我们发现 \(A(i)\) 和 \(B(j)\) 都是已知的,而 \(A(i)\) 只与当前位置有关,\(B(j)\) 只与之前的位置有关,可以视为决策。

由于存在 \(A(i)B(j)\) 这种既与当前位置有关,又与决策有关的东西,于是我们尝试将与决策有关的东西单独分离出来。我们对这个式子进行变换:

\[dp[j]+B(j)^2=2A(i)B(j)+dp[i]-A(i)^2
\]

可以将其视为一条斜率为 \(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] 玩具装箱的更多相关文章

  1. 洛谷P3195 [HNOI2008] 玩具装箱 [DP,斜率优化,单调队列优化]

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

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

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

  3. 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)

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

  4. [洛谷P3195][HNOI2008]玩具装箱TOY

    题目大意:有n个物体,大小为$c_i$.把第i个到第j个放到一起,容器的长度为$x=j-i+\sum\limits_{k-i}^{j} c_k$,若长度为x,费用为$(x-L)^2$.费用最小. 题解 ...

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

    Code: #include<cstdio> #include<algorithm> using namespace std; const int maxn = 100000 ...

  6. 洛谷 P3195 [HNOI2008]玩具装箱TOY

    题意简述 有n个物体,第i个长度为ci 将n个物体分为若干组,每组必须连续 如果把i到j的物品分到一组,则该组长度为 \( j - i + \sum\limits_{k = i}^{j}ck \) 求 ...

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

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

  8. 洛谷3195(HNOI2008)玩具装箱

    题目:https://www.luogu.org/problemnew/show/P3195 自己做斜率优化的第一道题. 推成斜率优化的样子很重要. 斜率优化的样子就是从 j 中求 i 的话,关系式里 ...

  9. 洛谷3195 [HNOI2008]玩具装箱TOY(斜率优化+dp)

    qwq斜率优化好题 第一步还是考虑最朴素的\(dp\) \[dp=dp[j]+(i-j-1+sum[i]-sum[j])^2 \] 设\(f[i]=sum[i]+i\) 那么考虑将上述柿子变成$$dp ...

随机推荐

  1. Ubuntu中类似QQ截图的截图工具并实现鼠标右键菜单截图

    @ 目录 简介: 安装: 设置快捷键: 实现鼠标右键菜单截图: 简介: 在Windows中用惯了强大易用的QQ截图,会不习惯Ubuntu中的截图工具. 软件名为火焰截图,功能类似QQ截图,可以设置快捷 ...

  2. ecshop 加入购物车和直接购买同时存在的方法

    一.首先将直接购买的链接设置为 <a href="javascript:bool =1;addToCart({$goods.goods_id})"> bool值为1,g ...

  3. Go学习【02】:理解Gin,搭一个web demo

    Go Gin 框架 说Gin是一个框架,不如说Gin是一个类库或者工具库,其包含了可以组成框架的组件.这样会更好理解一点. 举个 下面的示例代码在这:github 利用Gin组成最基本的框架.说到框架 ...

  4. linux帐户安全管理与技巧

    实验环境 CentosOS5.6试验台. 任务一:建立与删除普通用户账户,管理组 1)创建一个新用户user1 useradd user1 查看用户是否创建成功 2)创建一个新组group1 grou ...

  5. Java-Ide快速创建getter&setter方法

    1.右键 选择Generate 2.创建 类的equals方法

  6. Python Software Foundation

    The Python Software Foundation (PSF) is a 501(c)(3) non-profit corporation that holds the intellectu ...

  7. CF1119H-Triple【FWT】

    正题 题目链接:https://www.luogu.com.cn/problem/CF1119H 题目大意 \(n\)个可重集,第\(i\)个里有\(x\)个\(a_i\),\(y\)个\(b_i\) ...

  8. CF835E-The penguin‘s game【交互】

    正题 题目链接:https://www.luogu.com.cn/problem/CF835E 题目大意 长度为\(n\)的序列中有两个\(y\)其他都是\(x\),给出\(n,x,y\).你每次可以 ...

  9. Python3入门系列之-----异常处理

    前言 作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息,在前面我们没有提及,这章节我们会专门介绍. Python 有两种错误很容易辨认:语法错误和异常. Python ...

  10. Hyper-V CPU设置

    前言 最近在用Hyper-V测试项目,发现在运行过程中发现项目总数崩掉,几经发现有一个共性,CPU占用率100%,分析问题发现问题出在Hyper-V CPU设置上,Hyper-V装系统就不赘述了,网上 ...