HNOI2008玩具装箱 斜率优化
题目描述
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玩具装箱 斜率优化的更多相关文章
- BZOJ 1010 [HNOI2008]玩具装箱 (斜率优化DP)
题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=1010 思路 [斜率优化DP] 我们知道,有些DP方程可以转化成DP[i]=f[j]+x[i ...
- BZOJ 1010 HNOI2008 玩具装箱 斜率优化
题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1010 Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的 ...
- luogu3195/bzoj1010 玩具装箱(斜率优化dp)
推出来式子然后斜率优化水过去就完事了 #include<cstdio> #include<cstring> #include<algorithm> #include ...
- BZOJ1010玩具装箱 - 斜率优化dp
传送门 题目分析: 设\(f[i]\)表示装前i个玩具的花费. 列出转移方程:\[f[i] = max\{f[j] + ((i - (j + 1)) + sum[i] - sum[j] - L))^2 ...
- 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] ...
- BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 9812 Solved: 3978[Submit][St ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
- 【BZOJ 1010】 [HNOI2008]玩具装箱toy (斜率优化)
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 9330 Solved: 3739 Descriptio ...
- bzoj 1010 [HNOI2008]玩具装箱toy(DP的斜率优化)
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 7874 Solved: 3047[Submit][St ...
随机推荐
- Lumen开发:结合Redis实现消息队列(3)
4.运行队列监听器 开启任务监听器 Lumen包含了一个Artisan命令用来运行推送到队列的新任务.你可以使用queue:listen命令运行监听器: php artisan queue:liste ...
- windows10系统自带输入法不能切换中文如何解决
具体如下: 1.打开计算机管理软件,右击“开始”按钮,在弹出的菜单中选择“计算机管理”: 2.或在桌面右击“此电脑”图标,在弹出的菜单中选择“管理”: 3.在打开的计算机管理软件中,选择“系统工具”- ...
- Java 学习 day08
01-面向对象(多态-概念) package myFirstCode; /* 多态:可以理解为事务存在的多种体现形态. 人:男人,女人 动物:猫,狗 猫 x = new 猫(); 动物 x = new ...
- dubbo开发中使用到的一些服务配置方式
通过之前的学习了解了dubbo的常规的使用,下面我们看看特殊情况或者说真实环境下使用dubbo的一些配置实例. 一.一个接口有多个实现时可以使用group来区分 1.服务提供者配置 <?xml ...
- Alamofire 小试牛刀
1.定义请求头 let headers: HTTPHeaders = [ "token": "W4SIjb3gHgJqgG8LRWj0jM==", " ...
- nginx搭建服务
1.当然首先是安装nginx :http://nginx.org/en/download.html 2.一波安装之后 3.在nginx 文件夹打开命令行:cmd 4.开启nginx 服务命令:star ...
- C++, Java和C#的编译、链接过程解析
总是感觉java是解释性语言,转载下一篇感觉写的容易理解的文章 转自 http://www.cnblogs.com/rush/p/3155665.html 1.1.1 摘要 我们知道计算机不能直接理解 ...
- CF451E Devu and Flowers(容斥)
CF451E Devu and Flowers(容斥) 题目大意 \(n\)种花每种\(f_i\)个,求选出\(s\)朵花的方案.不一定每种花都要选到. \(n\le 20\) 解法 利用可重组合的公 ...
- Swift——(四)Swift中"#"的妙用
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/twlkyao/article/details/31350841 在Swift中," ...
- spark0.9.0安装
利用周末的时间安装学习了下最近很火的Spark0.9.0(江湖传言,要革hadoop命,O(∩_∩)O),并体验了该框架下的机器学习包MLlib(spark解决的一个重点就是高效的运行迭代算法),下面 ...