题目描述

P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京。他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中。P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的。同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物,形式地说如果将第i件玩具到第j个玩具放到一个容器中,那么容器的长度将为 x=j-i+Sigma(Ck) i<=K<=j 制作容器的费用与容器的长度有关,根据教授研究,如果容器长度为x,其制作费用为(X-L)^2.其中L是一个常量。P教授不关心容器的数目,他可以制作出任意长度的容器,甚至超过L。但他希望费用最小.

输入格式:

第一行输入两个整数N,L.接下来N行输入Ci.1<=N<=50000,1<=L,Ci<=10^7

输出格式:

输出最小费用

首先,这道题我们可以把所有的玩具长度加1,让后让L加1,就不存在什么填充物之类的,从而将这个问题转化为:把一个序列分为若干段,使得((每一段的和与常数L的差)的平方)相加起来的和最小。

那我们显而易见就先对这个序列求出每一个位置的前缀和,然后一个O(n^2)的dp就很明显了:

设f[i]表示恰好分完前i个数的最小代价,p[i]表示前i个数的和。

考虑转移:f[i]=min{ f[j]+(p[i]-p[j]-L)^2 }(0<=j<i)

然而,n<=50000,复杂度肯定会爆炸,所以我们需要优化这个dp,但是由于状态至少是线性的(反正我是想不出来),因而我们只能优化转移。

从转移方程入手:

f[i]=min{ f[j]+((p[i]-L)-p[j])^2 }(0<=j<i)

=(p[i]-L)^2+min{ f[j] + p[j]^2 - 2*p[i]*p[j] + 2*L*p[j] }

=(p[i]-L)^2+min{ f[j] + p[j]^2 + 2*L*p[j] - 2*p[i]*p[j] }

对于每一个i,有p[i]是定值,我们可以在dp的时候顺便用t[i]储存f[i] + p[i]^2 + 2*L*p[i]。

所以这个式子又变成了

f[i]-(p[i]-L)^2=min{ t[j] - 2*p[i]*p[j] }(0<=j<i)

我们若想f[i]-(p[i]-L)^2最小,设f[i]-(p[i]-L)^2=b,f[i]从j转移,则有,t[j]=2*p[j]*p[i]+b。

这个式子特别像一次函数的解析式,这时我们又发现对于i,p[i]确定,而且p数组满足单调递增,我们就可以想象平面上有若干个点,第j个点坐标是(p[j],t[j])。而我们需要找到一条斜率确定为2*p[i]并且过这些点中某一个点的直线,使他的截距(即上文中提到的b)最小。由于p[i]单调递增,因此每个i所对应的斜率也是单调递增的,并且将第i个点加入后第i个点一定是最靠右的。

这时我们就可以用单调队列维护一个下凸壳,每次从队首的点转移,若队首的点不是最优的(不如队列中第二个点更优),就把队首弹出,然后每次转移完f[i]时更新t[i],并将i压入单调队列中。

注意初始时队中应该有一个点(0,0)。

这个图有点抽象,图中的斜率远小于实际

AC代码如下

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 500020
using namespace std;
LL read(){
LL nm=0ll,fh=1ll;char cw=getchar();
for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=getchar()) nm=nm*10ll+(cw-'0');
return nm*fh;
}
LL n,f[M],L,p[M],t[M],rem,now,cnt,q[M][2],hd,tl=1;
LL gt_ans(LL k,LL pos){LL y=q[pos][1],x=q[pos][0];return y-x*k*2;}
int main(){
n=read(),L=read()+1;
for(LL i=1;i<=n;i++){
p[i]=p[i-1]+read()+1;
while(gt_ans(p[i],hd)>=gt_ans(p[i],hd+1)&&hd+1<tl) hd++;
f[i]=gt_ans(p[i],hd)+(p[i]-L)*(p[i]-L);
t[i]=p[i]*p[i]+2*L*p[i]+f[i];
while(hd+1<tl&&(t[i]-q[tl-1][1])*(q[tl-1][0]-q[tl-2][0])<=(q[tl-1][1]-q[tl-2][1])*(p[i]-q[tl-1][0])) tl--;
q[tl][0]=p[i],q[tl++][1]=t[i];
}
printf("%lld\n",f[n]);
return 0;
}

  

HNOI2008玩具装箱 斜率优化的更多相关文章

  1. BZOJ 1010 [HNOI2008]玩具装箱 (斜率优化DP)

    题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=1010 思路 [斜率优化DP] 我们知道,有些DP方程可以转化成DP[i]=f[j]+x[i ...

  2. BZOJ 1010 HNOI2008 玩具装箱 斜率优化

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1010 Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的 ...

  3. luogu3195/bzoj1010 玩具装箱(斜率优化dp)

    推出来式子然后斜率优化水过去就完事了 #include<cstdio> #include<cstring> #include<algorithm> #include ...

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

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

  5. BZOJ 1010 玩具装箱(斜率优化DP)

    dp[i]=min(dp[j]+(sum[i]-sum[j]+i-j-1-L)^2) (j<i) 令f[i]=sum[i]+i,c=1+l 则dp[i]=min(dp[j]+(f[i]-f[j] ...

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

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9812  Solved: 3978[Submit][St ...

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

    1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...

  8. 【BZOJ 1010】 [HNOI2008]玩具装箱toy (斜率优化)

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9330  Solved: 3739 Descriptio ...

  9. bzoj 1010 [HNOI2008]玩具装箱toy(DP的斜率优化)

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 7874  Solved: 3047[Submit][St ...

随机推荐

  1. intellij idea pycharm phpstorm webstorm 这些编辑器像 sublime text 一样使用 ctrl d 来操作光标多选。

    在Windows 和 Linux 快捷键是 Alt+J,在 Mac OS X 系统下快捷键是 Ctrl+G . 参考 https://blog.jetbrains.com/phpstorm/2014/ ...

  2. 使用tomcat7-maven-plugin部署Web项目

      一.环境准备 我使用的环境是:Window 10.Tomcat 8.0.36.maven3.tomcat7-maven-plugin 2.2版本. 二.设置环境变量 安装Tomcat8.0.36和 ...

  3. Image Recognition

    https://www.tensorflow.org/tutorials/image_recognition

  4. appium报'Command 'D\:\\android-sdk-windows\\platform-tools\\adb.exe -P 5037 -s “adb device” shell pm clear appPackage' exited with code 1'

    解决方法:是因为手机开发者模式没有允许USB调试(安全模式),打开即可

  5. Django之stark组件1

    stark组件 stark组件是根据Django admin为原型写的一个组件,能够让我们告别增删改查.stark组件是可插拔试的组件, 移植性强,而且只用配置文件就能够得到想要的数据 一.stark ...

  6. Javamail 发送附件中文名过长以及乱码问题

      最近在弄javamail发送邮件当邮件里含有附件并且附件是中文的时候发送后就会出现乱码!! 通过javax.mail.internet.MimeUtility.encodeText()就可解决这个 ...

  7. 每天一个Linux命令(17)whereis命令

    whereis命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b).man说明文件(参数-m)和源代码文件(参数-s).如果省略参数,则返回所有信息.     (1)用法:   用法:    w ...

  8. 【leetcode刷题笔记】Length of Last Word

    Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...

  9. P1393 动态逆序对

    题目 P1393 动态逆序对 做题前写篇博客是个好方法 做法 题目规定仅有删除,给每个位置标个号,逆序对+时间轴,显然这是个三维偏序 很久没做过\(cdq\)了,就当模板题讲一下: 按删除的先后顺序为 ...

  10. hihocoder 第五十二周 高斯消元·二【高斯消元解异或方程 难点【模板】】

    题目地址:http://hihocoder.com/contest/hiho57/problem/1 输入 第1..5行:1个长度为6的字符串,表示该行的格子状态,1表示该格子是亮着的,0表示该格子是 ...