BZOJ 1010 HNOI2008 玩具装箱 斜率优化
题目链接:
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
3
4
2
1
4
Sample Output
HINT
题意概述:
现在有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 玩具装箱 斜率优化的更多相关文章
- BZOJ 1010 [HNOI2008]玩具装箱 (斜率优化DP)
题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=1010 思路 [斜率优化DP] 我们知道,有些DP方程可以转化成DP[i]=f[j]+x[i ...
- 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(DP的斜率优化)
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 7874 Solved: 3047[Submit][St ...
- Bzoj 1010: [HNOI2008]玩具装箱toy(斜率优化)
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MB Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定 ...
- BZOJ 1010 [HNOI2008]玩具装箱toy
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 7184 Solved: 2724[Submit][St ...
- BZOJ 1010: [HNOI2008]玩具装箱toy(斜率优化dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题意: 思路: 容易得到朴素的递归方程:$dp(i)=min(dp(i),dp(k)+(i-k ...
- BZOJ 1010 [HNOI2008]玩具装箱toy:斜率优化dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题意: 有n条线段,长度分别为C[i]. 你需要将所有的线段分成若干组,每组中线段的 ...
- BZOJ.1010.[HNOI2008]玩具装箱toy(DP 斜率优化/单调队列 决策单调性)
题目链接 斜率优化 不说了 网上很多 这的比较详细->Click Here or Here //1700kb 60ms #include<cstdio> #include<cc ...
随机推荐
- Unity3d Gis 坐标转换
最近在做unity3d与Gis结合的项目,最基本的就是坐标的转换问题,比如把经纬度为(166.23.9.27 , 39.55.15.74) 转换到unity里面成相应的位置点,废话不多说 上代码: u ...
- shell脚本中 [-eq] [-ne] [-gt] [-lt] [ge] [le]
-eq //等于 -ne //不等于 -gt //大于 (greater ) -lt //小于 (less) -ge //大于等于 -le //小于等于 在linux 中 命令执行状态:0 为真,其他 ...
- 安装sass遇到的坑
一.安装Sass https://www.sass.hk/install/ 根据网站的步骤进行安装 Ruby版本的选择 我第一次下载是在Ruby官网上下的2.5.0版本得ruby.然而下载了之后无(不 ...
- 『嗨威说』常见的C++函数模板整理(一)
开学两天,身上的职责直接变为两个班班长,三个小组组长,哇这事情估计够我忙活了,想躲都躲不掉啊,看来我还是真招人推荐各种管理职务啊,以后要是有人推荐我当经理啊领导啊该多好哈哈哈哈.记得今天奶奶生日,很开 ...
- MySQL中Date,DateTime,TimeStamp和Time的比较
名称 显示格式 显示范围 应用场景 后台取值 Date YYYY-MM-DD 1601-01-01 到 9999-01-01 当业务需求中只需要精确到天时, 可以用这个时间格式 @JSONField( ...
- gcc 手动安装
由于公司内部服务器没有联通外网,只能苦逼的手动安装gcc(自带的版本太老) rpm -ivh ppl-0.10.2-11.el6.x86_64.rpm rpm -ivh cloog-ppl-0.15. ...
- mongo数据库相关目录
mongodb的docker化安装 mongodb的windows系统下安装 grafana使用Prometheus数据源监控mongo数据库 mongodb副本集的docker化安装 mongodb ...
- webBrowser 应用编程函数总结
/*============================说明部分================================= 实现一下函数需包含头文件 #include <Winine ...
- 构造HTTP请求Header实现“伪造来源IP”
在阅读本文前,大家要有一个概念,在实现正常的TCP/IP 双方通信情况下,是无法伪造来源 IP 的,也就是说,在 TCP/IP 协议中,可以伪造数据包来源 IP ,但这会让发送出去的数据包有去无回,无 ...
- hive-show-partitions
展示分区命令 show partitions show partitions 可以展示这个表格之下的所有分区信息.这个命令常常用在使用SQL语句操作数据之前.举个简单的例子,如果我们想要根据uid融合 ...