BZOJ1010 [HNOI2008]玩具装箱toy
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!
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.1<=N<=50000,1<=L,Ci<=10^7
Output
输出最小费用
Sample Input
3
4
2
1
4
Sample Output
正解:决策单调性+DP+单调队列
解题报告:
许久之前的一道考试题目了,题解直接用学长的了:
首先贪心明显是错的(虽然可以过样例),想找反例的话随便看一个测试数据吧。
由于同一容器中玩具的编号必须是连续的,因此满足无后效性,可用动态规划解决。一个比较容易想到O(N^2 )的算法是,用F i 表示装前i个玩具的最少费用,S i 表示前i个玩具的总长度,则状态
转移方程为:
F i = min {F j + (S i − S j + i − (j + 1) − L) 2 }0≤j<i
但由于N 最大可达到50000,所以期望得分为10∼20分。
然而,真正颇为牛B的东西来了。
令S i ′ = S i + i, L ′ = L + 1,让我们重新观察原方程:
F i = min {F j + (S i ′ − S j ′ − L ′ ) 2 } 0≤j<i
令V j = F j + (S i ′ − S j ′ − L ′ ) 2 ,那么在x < y时,V x ≥ V y 可变形为:
F x − F y ≥ (S i ′ − S y ′ − L ′ ) 2 − (S i ′ − S x ′ − L ′ ) 2
⇒ F x − F y ≥ (2S i ′ − S x ′ − S y ′ − 2L ′ )(S x ′ − S y ′ )
⇒ F x − F y ≥ (2(S i ′ − L ′ ) − (S x ′ + S y ′ ))(S x ′ − S y ′ )
⇒ F x − F y ≥ 2(S i ′ − L ′ )(S x ′ − S y ′ ) − (S x ′ + S y ′ )(S x ′ − S y ′ )
⇒ F x − F y + S x ′ − S y ′ ≥ 2(S i ′ − L ′ )(S x ′ − S y ′ )
这样的话,如果对于当前的i,有x < y, V x ≥ V y ,那么对于以后更大的i,由于2(S i ′ − L ′ )的单调性,V x ≥ V y
将会恒成立,也就是说x不可能再成为最优决策,我们将永远不会再用到它。
因为决策i可能比原队列中的某些决策更优,如果不将这些肯定没用的决策删除,队列前面的非最优决策可能受到它们当中的某个决策“保护”而没有被删除,其实这样也就是保证函数G的值在Q中单调递增。
由于每个元素最多入队一次,出队一次,所以维护队列的时间复杂度为O(N ),状态转移为O(1),计算F 值为O(N ),所以总时间复杂度为O(N ) + O(1) × O(N ) = O(N )。
//It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const LL inf = (1LL<<);
const int MAXN = ;
int n,a[MAXN],dui[MAXN],head,tail;
LL L,f[MAXN],sum[MAXN],S[MAXN]; inline int getint()
{
int w=,q=; char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
} inline bool check(int x,int y,int i){
x=dui[x]; y=dui[y];
LL ji=f[x]-f[y]+S[x]*S[x]-S[y]*S[y];
LL comp=*(S[i]-L); comp*=S[x]-S[y];
if(ji>=comp) return true; return false;
} inline bool check2(int x,int y,int i){
x=dui[x]; y=dui[y];
LL ji1=f[x]-f[y]+S[x]*S[x]-S[y]*S[y]; ji1/=(S[x]-S[y]);
LL ji2=f[y]-f[i]+S[y]*S[y]-S[i]*S[i]; ji2/=(S[y]-S[i]);
if(ji1>=ji2) return true; return false;
} inline void work(){
n=getint(); L=getint(); for(int i=;i<=n;i++) a[i]=getint(),sum[i]=sum[i-]+a[i],S[i]=sum[i]+i;
head=tail=; dui[head]=; L++;
for(int i=;i<=n;i++) {
while(head<tail && check(head,head+,i)) head++;
f[i]=f[dui[head]]+(S[i]-S[dui[head]]-L)*(S[i]-S[dui[head]]-L);
while(head<tail && check2(tail-,tail,i)) tail--;
dui[++tail]=i;
}
printf("%lld",f[n]);
} int main()
{
work();
return ;
}
BZOJ1010 [HNOI2008]玩具装箱toy的更多相关文章
- bzoj1010[HNOI2008]玩具装箱toy 斜率优化dp
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 11893 Solved: 5061[Submit][S ...
- bzoj1010: [HNOI2008]玩具装箱toy(DP+斜率优化)
1010: [HNOI2008]玩具装箱toy 题目:传送门 题解: 很明显的一题动态规划... f[i]表示1~i的最小花费 那么方程也是显而易见的:f[i]=min(f[j]+(sum[i]-su ...
- [BZOJ1010] [HNOI2008] 玩具装箱toy (斜率优化)
Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...
- [bzoj1010](HNOI2008)玩具装箱toy(动态规划+斜率优化+单调队列)
Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有 的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1.. ...
- [BZOJ1010][HNOI2008]玩具装箱toy 解题报告
Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...
- BZOJ1010 [HNOI2008]玩具装箱toy 动态规划 斜率优化
原文链接http://www.cnblogs.com/zhouzhendong/p/8687797.html 题目传送门 - BZOJ1010 题意 一个数列$C$,然后把这个数列划分成若干段. 对于 ...
- 2018.09.05 bzoj1010: [HNOI2008]玩具装箱toy(斜率优化dp)
传送门 一道经典的斜率优化dp. 推式子ing... 令f[i]表示装前i个玩具的最优代价. 然后用老套路. 我们只考虑把第j+1" role="presentation" ...
- 题解【bzoj1010 [HNOI2008]玩具装箱TOY】
斜率优化动态规划可以用来解决这道题.同时这也是一道经典的斜率优化基础题. 分析:明显是动态规划.令\(dp[i]\)为前\(i\)个装箱的最小花费. 转移方程如下: \[dp[i]=\min\limi ...
- 【斜率优化】BZOJ1010 [HNOI2008]玩具装箱toy
[题目大意] P教授有编号为1...N的N件玩具,第i件玩具长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的.如果将第i件玩具到第j个玩具放到一 个容器中,那么容器的长度将为 x ...
随机推荐
- 043医疗项目-模块四:采购单模块—采购单明细查询(Dao,Service,Action三层)
前一篇文章我们做的是在医院的角度上添加在采购单里面添加药品.这一篇文章是查看我们添加的采购单信息. 我们先看一下要实现的效果:当: 按下确认添加时,会在这里 显示出刚才添加的数据. 好,我们就来做这个 ...
- Kafka是分布式发布-订阅消息系统
Kafka是分布式发布-订阅消息系统 https://www.biaodianfu.com/kafka.html Kafka是分布式发布-订阅消息系统.它最初由LinkedIn公司开发,之后成为Apa ...
- Android 常用的adb命令
1.安装APK(如果加 -r 参数,保留已设定数据,重新安装filename.apk) adb install xxx.apk adb install -r xxx.apk 2.卸载APK(如果加 - ...
- codevs3143 二叉树的序遍历
难度等级:白银 3143 二叉树的序遍历 题目描述 Description 求一棵二叉树的前序遍历,中序遍历和后序遍历 输入描述 Input Description 第一行一个整数n,表示这棵树的节点 ...
- codevs2010 求后序遍历
难度等级:白银 2010 求后序遍历 题目描述 Description 输入一棵二叉树的先序和中序遍历序列,输出其后序遍历序列. 输入描述 Input Description 共两行,第一行一个字符串 ...
- 异常和IO
异常 异常是指java程序运行时(非编译)所发生的非正常情况或错误. Java对异常进行了分类,不同类型的异常分别用不同的 Java 类表示,所有异常的根类为 java.lang.Throwable, ...
- list使用例子(转)
例子: 在vs2010中创建一个winform的解决方案,然后定义一个类Person,Person.cs 的代码如下: using System;using System.Collections.Ge ...
- WPF 小技巧
在使用mvvm模式开发时,对于Command的绑定是一件很伤脑筋的事情,尽管有强大的Blend类库支持: xmlns:Custom="http://www.galasoft.ch/mvvml ...
- Nodejs爬虫进阶=>异步并发控制
之前写了个现在看来很不完美的小爬虫,很多地方没有处理好,比如说在知乎点开一个问题的时候,它的所有回答并不是全部加载好了的,当你拉到回答的尾部时,点击加载更多,回答才会再加载一部分,所以说如果直接发送一 ...
- Rest API 开发 学习笔记(转)
Rest API 开发 学习笔记 概述 REST 从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源的表示方式.获得这些表徵致使这些应用程序转变了其状态.随着 ...