洛谷P1848 书架
好,我一直以为书架是splay,然后发现还有个优化DP的书架。妃的书架
蓝书和PPT上面都讲了,应该比较经典吧。
题意:
有n个物品,每个都有宽,高。
把它们分成若干段,使得每段的最大值的总和最小。且每段的总宽度不超过L。
n <= 100000
解:
首先有个很显然的DP是f[i] = min(f[j] + max(j + 1, i)), sum[i] - sum[j] <= L
然后如何优化呢?因为有max函数(非线性)所以难以单调队列。把决策打出来发现不单调。无计可施???
发现当i固定的时候,max(j + 1, i)是一段一段单减的。这样相当于能确定状态转移方程中的后者。
再看前者,f[j]这个东西,其实是单调不减的。证明:把f[j - 1]按照f[j]的方式划分即可<=f[j]。
怎么利用呢?朴素的想法是把每一个数前面最大的数用单调栈求出来,记为to[]数组。
那么每次转移的时候跳to[]即可。可以发现在区间(to[i], i)之间的转移都不优于to[i]。
这里忽视了一个小问题,有个宽度限制在这里。我的解决办法是用pos记录最早的一个能够转移过来的位置。pos的维护显然是线性的。
这个好想好写的东西最坏复杂度还是n²,递增序列就能卡掉,然而交上去有90分......
来考虑正解。我们能不能每次不跳to[]链,而是更快的求出最小值来转移呢?
很容易(困难)想到用堆维护。对于失效的转移用延迟删除法。
问题就只剩如何判断转移失效了。
如果转移的j < pos,显然不行。此外,如果j不在以i开头的to链上,也是不行的。
有个朴素的想法是用数组维护是否在to链上,即每次把i前面比i小的舍去,但是又会被递增卡成n²。
仔细思考,发现以i开头的to链就是单调栈在处理到i时的栈内元素。
于是我们一边DP一边维护单调栈,只需判断j是在否在栈中即可。
至此,时间复杂度优化为nlogn,可以通过此题。
记得开long long
#include <cstdio>
#include <algorithm>
#include <queue>
#define mp std::make_pair typedef long long LL;
const int N = ; LL f[N], sum[N];
int st[N][], pow[N], n, to[N], p[N], top;
bool in_stk[N];
std::priority_queue<std::pair<LL, int> > Q; inline void STinit() {
int j = , lm = ;
while(( << lm) <= n) {
while(j < ( << (lm + )) && j <= n) {
pow[j] = lm;
j++;
}
lm++;
}
for(int j = ; j < lm; j++) {
for(int i = ; i + ( << j) - <= n; i++) {
st[i][j] = std::max(st[i][j - ], st[i + ( << (j - ))][j - ]);
}
}
return;
} inline int getmax(int l, int r) {
int t = pow[r - l + ];
return std::max(st[l][t], st[r - ( << t) + ][t]);
} int main() {
int L;
scanf("%d%d", &n, &L);
for(int i = ; i <= n; i++) {
scanf("%d%lld", &st[i][], &sum[i]);
sum[i] += sum[i - ];
f[i] = 1ll << ;
} STinit();
st[][] = 0x7f7f7f7f;
to[] = -; int pos = ;
for(int i = ; i <= n; i++) {
while(st[i][] >= st[p[top]][]) {
in_stk[p[top]] = ;
top--;
}
to[i] = p[top];
p[++top] = i;
in_stk[i] = ; Q.push(mp(- * (f[to[i]] + getmax(to[i] + , i)), i)); while(sum[i] - sum[pos] > L) {
pos++;
}
while((!Q.empty()) && (to[Q.top().second] < pos || (!in_stk[Q.top().second]))) {
Q.pop();
}
if(!Q.empty()) {
f[i] = - * Q.top().first;
}
f[i] = std::min(f[i], f[pos] + getmax(pos + , i));
}
/*for(int i = 1; i <= n; i++) {
printf("%lld ", f[i]);
}*/
printf("%lld", f[n]);
return ;
}
AC代码
但是还有很多可以改进的地方。
比如to这个数组可否舍去?ST表可否舍去?我是懒得优化了T_T
洛谷P1848 书架的更多相关文章
- 洛谷P3850 书架
题目描述 Knuth先生家里有个精致的书架,书架上有N本书,如今他想学到更多的知识,于是又买来了M本不同的新书.现在他要把新买的书依次插入到书架中,他已经把每本书要插入的位置标记好了,并且相应的将它们 ...
- 洛谷P2468 SDOI 2010 粟粟的书架
题意:给你一个矩形书架,每个点是这本书的页数,每次询问(x1,y1)(x2,y2)这个小矩形里最少需要取几本书使得页数和等于Hi. 题解:小数据二位前缀和预处理+二分答案,大数据一行所以用主席树做,感 ...
- [洛谷P2596] [ZJOI2006]书架
洛谷题目链接:书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后 ...
- 洛谷P2468 [SDOI2010]粟粟的书架
来了来了,随便拽一道题写题解[大雾] 最近发现自己基础奇差于是开始复习之前学过的东西,正好主席树我几乎完全没学会,然后打开洛谷试炼场… 发现了这么一道二合一的题. 这道题其实分成两个部分,前50%是一 ...
- 洛谷P2464 [SDOJ2008]郁闷的小J
洛谷P2464 [SDOJ2008]郁闷的小J 题目描述 小J是国家图书馆的一位图书管理员,他的工作是管理一个巨大的书架.虽然他很能吃苦耐劳,但是由于这个书架十分巨大,所以他的工作效率总是很低,以致他 ...
- 洛谷 P1103 书本整理(动规)
洛谷 P1103 书本整理 题目描述 Frank是一个非常喜爱整洁的人.他有一大堆书和一个书架,想要把书放在书架上.书架可以放下所有的书,所以Frank首先将书按高度顺序排列在书架上.但是Frank发 ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
随机推荐
- Linux 文件及目录管理命令基础
pwd 显示当前所在目录 cd 切换目录 cd 命令语法 cd [选项] 目录 cd 的常用选项: cd ~ /cd 切换到当前用户的加目录 cd . 保持当前目录不变 cd .. 切换到上级目录 ...
- python之路--类与类之间的关系
类和类之间的关系 在我们的世界中事物和事物之间总会有一些联系. 在面向对象中. 类和类之间也可以产生相关的关系 1. 依赖关系 执行某个动作的时候. 需要xxx来帮助你完成这个操作. 此时的关系是最轻 ...
- SQL Server2012数据库开启远程连接
在我们使用SQL Server数据库的时候很重要的一点就是开启数据库的远程连接,这是因为很多时候数据库部署在远程的服务器上会比较方便,而部署在客户端的话,由于客户端不固定,所以需要经常去部署,这样容易 ...
- JQ获取URL中是否含有某个字符的话,对页面进行某种操作
一.//JQ获取URL中是否含有某个字符的话,对页面进行某种操作 例:如果URL中含有xia的字符,就在页面引入一个cssvar str=window.location.href; //获取地址栏UR ...
- Vuex的API文档
前面的话 本文将详细介绍Vuex的API文档 概述 import Vuex from 'vuex' const store = new Vuex.Store({ ...options }) [构造器选 ...
- Nintex History in Form Table
一.设置参数 二.调用WebService 三.For Each 调用 四.拼写HTML Table 结果: 特别提示:过滤人只要根据人来循环即可
- git在Linux下的安装
参考:https://git-scm.com/book/zh/v1/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git Git 的工作需要调用 curl,zlib,op ...
- pycharm pip 源修改以及包管理(转载)
转载自(https://www.u3v3.com/ar/1352) pycharm下如何将默认的pip源改成国内能快速访问的源, 以及如何进行包管理 pycharm 是一款进行python项目开发的利 ...
- 第五十六 css选择器和盒模型
1.组合选择器 群组选择器 #每个选择为可以位三种基础选择器任意一个,用逗号隔开,控制多个. div,#div,.div{ color:red } 后代(子代)选择器 .sup .sub{ 后代 } ...
- 李昊大佬的CV模板
#include<cstdio> #include<iostream> #include<cstdlib> #include<iomanip> #inc ...