题目链接:

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. 对象的比较与排序(三):实现IComparable<T>和IComparer<T>泛型接口

    来源:http://www.cnblogs.com/eagle1986/archive/2011/12/06/2278531.html 1:比较和排序的概念 比较:两个实体类之间按>,=,< ...

  2. JavaScript 笔记总结

    一.js的简介  1.js是什么 js是可以嵌入到html中,是 基于对象 和 事件驱动 的 脚本语言 特点: (1)交互性 (2)安全性:js不能访问本地磁盘 (3)跨平台:浏览器中都具备js解析器 ...

  3. Linux7静默安装Oracle11g教程,亲测实用有效!

    1.查看swap大小,若小于150M,需添加增加虚拟空间 dd if=/dev/zero of=/swapadd bs=1024 count=2006424 mkswap /swapadd swapo ...

  4. 分组函数group by和Oracle中分析函数partition by的用法以及区别

    1.分组函数group by和Oracle中分析函数partition by的用法以及区别 2.开窗函数.

  5. wubiuefi-支持新版本ubuntu的wubi

    由于某些原因,ubuntu官方不再提供新版的wubi 这就使得部分想快速且安全尝试新版ubuntu的用户望而却步 最近在外文网站找到了wubi的新版本wubiuefi,支持最新版的ubuntu 目前支 ...

  6. leetcode算法之 Single Number

    题目描述: 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 要求:  时间复杂度O(n),空间复杂都O(1) 示例: 输入: [2,2,1] 输 ...

  7. (暴力碾标算)NOIP模拟赛 宗教仪式

    题意: 一个模式串,一个文本串,现定义最大失配值为k 求文本中最大失配值<=k的长度为len(模式串)的字串个数 失配值=当前字串中与模式串不同的字符个数 思路: 暴力,加一个跳出剪枝,居然过了 ...

  8. 【转载】Git忽略规则和.gitignore规则不生效的解决办法

    原文:https://www.cnblogs.com/zhangxiaoliu/p/6008038.html Git忽略规则: 在git中如果想忽略掉某个文件,不让这个文件提交到版本库中,可以使用修改 ...

  9. Java常用的正则校验

    1.非负整数: (^[1-9]+[0-9]*$)|(^[0]{1}$) 或 (^[1-9]+[0-9]*$)|0 2.非正整数: (^-[1-9]+[0-9]*$)|(^[0]{1}$) 或 (^-[ ...

  10. Ubuntu 16.04 Server 版安装过程图文详解

    进入系统安装的第一个界面,开始系统的安装操作.每一步的操作,左下角都会提示操作方式!! 1.选择系统语言-English 2.选择操作-Install Ubuntu Server 3.选择安装过程和系 ...