题目链接:

http://www.lydsy.com/JudgeOnline/problem.php?id=1010

Description

  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。但他希望费用最小。

Input

第一行输入两个整数N,L.接下来N行输入Ci。

Output

输出最小费用

Sample Input

5 4
3
4
2
1
4

Sample Output

1

HINT

 
1<=N<=50000,1<=L,Ci<=10^7
 
 
 
 
 

题意概述:

  现在有N件物品,每件物品有一个长度Ci,现在要求把这些物品分组,每组必须是连续的一段,假如把第i~j件物品分成一组,那么这一组的长度x为j-i+sum{ck|i<=k<=j},同时这一组的代价为(x-L)^2,L是一个常量。现在问将这些物品分组的最小代价。1<=N<=50000,1<=L,Ci<=10^7.

分析:

  容易看出来一个dp模型。

  令f(i)表示将前i个物品分组的最小代价。

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

  令wi=i+sum[i],LL=L+1,去掉min,改写式子得到:

  [2*wj*LL+wj^2+f(j)]=wi*(2*wj)+f(i)-(wi-LL)^2

  如果把(2*wj,2*wj*LL+wj^2+f(j))看成点,那么现在要做的就是在一个点集中找到一个点使得f(i)-(wi-LL)^2最小。

  每次计算的直线的斜率有单调递增的趋势。因为是斜率始终大于0并且要让纵截距最小,于是我们需要维护一个下凸壳。因为斜率具有单调性,所以说每一次计算的时候都从队首取出一个元素计算,并且和队首后面的元素计算出来的答案比较。如果队首的答案更劣,那么直接出队,因为斜率具有单调性,之后一定也不会用到这个点了。每一次计算完之后插入新点,对于新点来说从队尾开始看起。如果这个点和队尾前一个点的斜率小于队尾和队尾前一个点的斜率,那么说明队尾的点被包住了,出队,最后把这个点甩进去(因为插入的点的横坐标都是单调递增的,所以说不会有一些奇奇怪怪的问题)。两个出队操作都在当前点不更加优秀或者队列中只有一个点的时候停止。

  时间复杂度O(N)。

  注意两个很sb的问题:1.初始化的时候要用0来初始化,表示这个物品和前面所有的物品分成一组;2.因为我们引用了斜率这个概念,所以在推式子的时候一定记得把式子写成斜截式!!!

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
const int maxn=;
typedef long long LL; int N,L,C[maxn];
LL f[maxn],sum[maxn];
struct XY{ LL x,y; }mq[maxn]; int front,rear; void data_in()
{
scanf("%d%d",&N,&L);
for(int i=;i<=N;i++) scanf("%d",&C[i]);
}
LL X(int i){ return *(i+sum[i]); }
LL Y(int i){ return *(i+sum[i])*(L+)+(i+sum[i])*(i+sum[i])+f[i]; }
double getk(const XY &a,const XY &b){ return 1.0*(a.y-b.y)/(a.x-b.x); }
void work()
{
for(int i=;i<=N;i++) sum[i]=sum[i-]+C[i];
mq[rear++]=(XY){X(),Y()};
XY p;
for(int i=;i<=N;i++){
while(rear-front>&&getk(mq[front],mq[front+])<i+sum[i]) front++;
f[i]=-(i+sum[i])*mq[front].x+mq[front].y+(i+sum[i]-L-)*(i+sum[i]-L-);
p=(XY){X(i),Y(i)};
while(rear-front>&&getk(p,mq[rear-])<getk(mq[rear-],mq[rear-])) rear--;
mq[rear++]=p;
}
cout<<f[N]<<'\n';
}
int main()
{
data_in();
work();
return ;
}

BZOJ 1010 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]玩具装箱toy [DP 斜率优化]

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

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

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

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

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

  5. Bzoj 1010: [HNOI2008]玩具装箱toy(斜率优化)

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MB Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定 ...

  6. BZOJ 1010 [HNOI2008]玩具装箱toy

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

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

    http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题意: 思路: 容易得到朴素的递归方程:$dp(i)=min(dp(i),dp(k)+(i-k ...

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

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题意: 有n条线段,长度分别为C[i]. 你需要将所有的线段分成若干组,每组中线段的 ...

  9. BZOJ.1010.[HNOI2008]玩具装箱toy(DP 斜率优化/单调队列 决策单调性)

    题目链接 斜率优化 不说了 网上很多 这的比较详细->Click Here or Here //1700kb 60ms #include<cstdio> #include<cc ...

随机推荐

  1. 运行Python

    安装好python环境,在Windows系统下运行cmd命令行,是windows提供的命令行模式. 在命令行下,可以执行python进入Python交互式环境,也可以执行python hello.py ...

  2. 18年selenium3+python3+unittest自动化测试教程(上)

    第一章 自动化测试课程介绍和课程大纲 1.自动化测试课程介绍 简介:讲解什么是自动化测试和课程大纲讲解,课程需要的基础和学后的水平 python3.7+selenium3 pycharm 第二章自动化 ...

  3. c#的二进制序列化组件MessagePack介绍

    c#的序列化有多种,我一般喜欢用第三方组件,一个公共组件要拿出来用,而且支持很多语言,甚至以此谋生,肯定有其优势. 有或者说存在必然有其合理性,经过几年开发,我更加喜欢第三方的东西,类似序列化的东西. ...

  4. ABAP术语-Data Browser

    Data Browser 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/21/1046858.html Tool for displayin ...

  5. 关于对连接数据库时出现1130-host “**” is not allowed to connect to this MySql/mariadb server 的错误解决方法

    在完成mariadb的搭建后,在端口与防火墙均为正常的情况下,出现了1130- Host xxx is not allowed to connect to this MariaDb server 的情 ...

  6. ASP.NET Web用户控件

    用户控件可用来实现页面中可重用的代码,是可以一次编写就多处方便使用的功能块.它们是 ASP.NET控件封装最简单的形式.由于它们最简单,因此创建和使用它们也是最简单的.用户控件实际上是把已有的服务器控 ...

  7. 虚拟环境管理之virtualenvwrapper

    上一篇写了下在linux上使用python的虚拟环境, 干脆把virtualenvwrapper也写一下 1.为什么要用virtualenvwrapper virtualenv 的一个最大的缺点就是: ...

  8. Python的virtualenv你用过吗?

    1. 为什么要有virtualenv 在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题: 亦或者是在开发过程中不想让物理环境里充斥各种各样的库,引发未来的依赖灾 ...

  9. MIP组件开发 自定义js组件开发步骤

    什么是百度MIP? MIP(Mobile Instant Pages - 移动网页加速器)主要用于移动端页面加速 官网参考:https://www.mipengine.org/doc/00-mip-1 ...

  10. PHP令人困惑的strtotime

    经常会有人被strtotime结合-1 month, +1 month, next month的时候搞得很困惑, 然后就会觉得这个函数有点不那么靠谱, 动不动就出问题. 用的时候就会很慌… 比如:今天 ...