bzoj 1010 玩具装箱toy -斜率优化
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
5 4
3
4
2
1
4
Sample Output
1
先推出普通dp的方程 f[i] = min{f[j] + (sum[i] - sum[j] + i - j - 1 - L)2}
这方程明显是O(n2)级别的,再看看这卖萌的数据范围,不用质疑,铁定超时。还是来考虑一下优化(例如斜率优化)吧。由于这方程长得太丑了,于是决定简化一下
设S(i) = sum[i] + i,C = L + 1
于是方程变成了这样 f[i] = min{f[j] + (S(i) - S(j) - C)2}
现在假设在状态i之前有两个可以转移到i的两个状态j, k(j < k),现在使j比k更优,那么它要满足
f[j] + (S(i) - S(j) - C)2 < f[k] + (S(i) - S(k) - C)2
看平方不爽,而且无法化简,果断完全平方公式拆掉
f[j] + [S(i) - (S(j) + C)]2 < f[k] + [S(i) - (S(k) + C)]2
f[j] + (S(j) + C)2 - 2S(i)[S(j) + C] < f[j] + (S(k) + C)2 - 2S(i)[S(k) + C]
(其实可以一起拆掉,只不过中途有些地方可以直接"抵消")继续"拆"括号,移项
f[j] + S(j)2 + 2S(j)C - 2S(i)[S(j) - S(k)] < f[k] + S(k)2 + 2S(k)C
继续,右边只留一个和i有关的单项式
(f[j] + S(j)2 + 2S(j)C) - (f[k] + S(k)2 + 2S(k)C) < 2S(i)[S(j) - S(k)]
继续移项,右边只留和i有关的式子
注意,S(i)是单调递增,所以S(j) - S(k) < 0,移项的时候不等号方向相反,于是我们愉快地得到了斜率方程(干什么?斜率优化去掉一个n)。
对于状态i,用(f[i] + S(i)2 + 2S(i)C)作纵坐标,2S(i)作横坐标,删掉上凸点,维护一条斜率递增的折线即可。
Code
/**
* bzoj
* Problem#1010
* Accepted
* Time:172ms
* Memory:2468k
*/
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
typedef bool boolean;
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-');
if(x == '-'){
aFlag = -;
x = getchar();
}
for(u = x - ''; isdigit((x = getchar())); u = u * + x - '');
ungetc(x, stdin);
u *= aFlag;
} template<typename T>
class IndexedDeque{
public:
T* list;
int pfront;
int prear;
IndexedDeque():list(NULL), pfront(), prear(){ }
IndexedDeque(int size):pfront(), prear(){
list = new T[size];
}
void push_front(T x){ list[--pfront] = x; }
void push_back(T x) { list[prear++] = x; }
void pop_front() { ++pfront; }
void pop_back() { --prear; }
T front() { return list[pfront]; }
T rear() { return list[prear - ]; }
T& operator [](int pos){ return list[pfront + pos]; }
int size() { return prear - pfront; }
}; int n, L;
long long* f;
long long* sum;
int C; #define s(i) (sum[(i)] + (i))
#define y_pos(i) (f[(i)] + pow2(s(i)) + 2 * C * s(i))
#define x_pos(i) (2 * s(i)) template<typename T>
inline long long pow2(T x){ return x * x; }
inline long long segsum(int from, int end){ return sum[end] - sum[from - ]; }
inline double slope(long long x1, long long y1, long long x2, long long y2){ return (y2 - y1) * 1.0 / (x2 - x1); }
inline double slope(int j, int k){ return slope(x_pos(j), y_pos(j), x_pos(k), y_pos(k)); }
inline double cmpSlope(int j, int k, int i){ return slope(x_pos(j), y_pos(j), x_pos(k), y_pos(k)) - s(i); } inline void init(){
readInteger(n);
readInteger(L);
sum = new long long[(const int)(n + )];
f = new long long[(const int)(n + )];
sum[] = ;
for(int i = , a; i <= n; i++){
readInteger(a);
sum[i] = sum[i - ] + a;
}
} IndexedDeque<int> que;
inline void solve(){
C = L + ;
que = IndexedDeque<int>( * n);
que.push_back();
f[] = ;
for(int i = ; i <= n; i++){
while(que.size() > && cmpSlope(que[], que[], i) <= ) que.pop_front();
int p = que.front();
f[i] = f[p] + pow2(segsum(p + , i) + i - p - C);
while(que.size() > && slope(que[que.size() - ], que[que.size() - ]) >= slope(que[que.size() - ], i)) que.pop_back();
que.push_back(i);
}
printf("%lld\n", f[n]);
} int main(){
init();
solve();
return ;
}
(2017-2-2,更正之前贴错的代码
2017-5-6,更正打错的内容)
bzoj 1010 玩具装箱toy -斜率优化的更多相关文章
- BZOJ 1010: 玩具装箱toy (斜率优化dp)
Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
- Bzoj 1010: [HNOI2008]玩具装箱toy(斜率优化)
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MB Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定 ...
- bzoj1010[HNOI2008]玩具装箱toy 斜率优化dp
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 11893 Solved: 5061[Submit][S ...
- 『玩具装箱TOY 斜率优化DP』
玩具装箱TOY(HNOI2008) Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊 ...
- BZOJ 1010 玩具装箱toy(斜率优化DP)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题目大意:P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他 ...
- BZOJ 1010 玩具装箱toy(四边形不等式优化DP)(HNOI 2008)
Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...
- 【bzoj1010】[HNOI2008]玩具装箱toy 斜率优化dp
题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...
- [luogu3195 HNOI2008] 玩具装箱TOY (斜率优化dp)
题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...
随机推荐
- pyobjc-framework-Cocoa 5.1.2
Introduction — PyObjC - the Python to Objective-C bridge https://pyobjc.readthedocs.io/en/latest/ py ...
- disk_free_space
$df = disk_free_space('/')/1024/1024/1024; $df_c = disk_free_space("c:"); $df_d = disk_fre ...
- iOS多线程编程之线程的状态(转载)
一.简单介绍 线程的创建: self.thread=[[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil]; ...
- 虚拟机中实现Linux与Windows之间的文件传输
虚拟机中实现Linux与Windows之间的文件传输 标签: linux 2016年06月28日 11:17:37 2092人阅读 评论(0) 收藏 举报 分类: linux(2) 一.配置环 ...
- [py]类和实例方法/内建方法
内建方法 dir(__builtins__) 类和实例方法对比 class person: def __init__(self, job): self.job = job name = "m ...
- Period(sdut2476)
[题目大意]:给定一个字符串,求到哪一位时的字串是前几位循环组成的,并求出循环次数. 思路:求每个前缀的最小循环周:从i到n枚举len,如果len%(len-next[len])==0,则这个前缀是由 ...
- jenkins 项目发布脚本
构建shell #!/bin/bash ########################################################################## 编译部分 ...
- pem转pfx
openssl req -new -key privkey.pem -out root.csr openssl x509 -req -days -sha1 -extensions v3_ca -sig ...
- 计算auc-python/awk
1.自己写的计算auc的代码,用scikit-learn的auc计算函数sklearn.metrics.auc(x, y, reorder=False)做了一些测试,结果是一样的,如有错误,欢迎指正. ...
- unity3d-准备工作
1.软件下载 想进行unity3d游戏开发,首先unity3d官网下载软件:unity3d下载 2.运行游戏界面 3.安装Visual Studio Tools for Unity unity3d自带 ...