[Luogu1848][USACO12OPEN]书架Bookshelf DP+set+决策单调性
题目链接:https://www.luogu.org/problem/show?pid=1848
题目要求书必须按顺序放,其实就是要求是连续的一段。于是就有DP方程$$f[i]=min\{f[j]+max\{h_k\}\}$$其中的k以及j的关系应该满足$$\sum_{k=j+1}^iw_k<=L$$
这样是$O(n^2)$的肯定不行。发现对于一个$h[i]$到前一个比它大的$h[j]$之间,都被$h[i]$所影响这,且这些影响某一段区间的关键点是单调下降的,同时发现$f[j]$总不会比$f[j+1]$更劣,证明显然。
于是我们只需要维护这样一个关键点集就可以从中取得最优答案。观察DP方程中的条件限制,发现前面的点可能会被从前往后舍去,而后面的点可以把之前的点给覆盖掉,想到用单调队列维护。
队首元素的删除用$w$的区间和来维护,队尾元素则直接用新加入的$h[i]$不断合并掉就好了。
然后对于每一个当前合法的关键点,我们都需要记录其对应的答案,每次取最小值。不仅需要插入,同时还需要从中删除掉不合法的答案。我们可以用双堆或者平衡树来做,当然set也是可以的。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
int inline readint(){
int Num;char ch;
while((ch=getchar())<''||ch>'');Num=ch-'';
while((ch=getchar())>=''&&ch<='') Num=Num*+ch-'';
return Num;
}
int n,m;
int h[],w[],la;
ll f[],sum;
int q[],head,tail;
bool in[];
multiset <ll> s;
// f[i]=f[j]+max(h[k]) sigma(w[k])<=L k:i->j+1
int main(){
n=readint();
m=readint();
la=head=q[]=;
tail=sum=;
in[]=true;
for(int i=;i<=n;i++){
h[i]=readint();
w[i]=readint();
sum+=w[i];
while(sum>m){
if(in[la]){
s.erase(f[la-]+h[la]);
in[la]=false;
head++;
}
else h[la]=h[la-];
sum-=w[la++];
}
if(!in[la]){
h[la]=h[la-];
s.insert(f[la-]+h[la]);
q[--head]=la;
in[la]=true;
}
q[++tail]=i;
s.insert(f[i-]+h[i]);
in[i]=true;
while(head<=tail&&h[q[tail]]<=h[i]){
s.erase(f[q[tail]-]+h[q[tail]]);
in[q[tail]]=false;
tail--;
}
h[q[++tail]]=h[i];
s.insert(f[q[tail]-]+h[q[tail]]);
in[q[tail]]=true;
f[i]=*s.begin();
}
printf("%lld\n",f[n]);
return ;
}
[Luogu1848][USACO12OPEN]书架Bookshelf DP+set+决策单调性的更多相关文章
- [BZOJ2739]最远点(DP+分治+决策单调性)
根据旋转卡壳,当逆时针遍历点时,相应的最远点也逆时针转动,满足决策单调性.于是倍长成链,分治优化DP即可,复杂度O(n^2). #include<cstdio> #include<a ...
- luogu P1721 [NOI2016]国王饮水记 斜率优化dp 贪心 决策单调性
LINK:国王饮水记 看起来很不可做的样子. 但实际上还是需要先考虑贪心. 当k==1的时候 只有一次操作机会.显然可以把那些比第一个位置小的都给扔掉. 然后可以得知剩下序列中的最大值一定会被选择. ...
- [USACO12OPEN]书架Bookshelf
Description 当农夫约翰闲的没事干的时候,他喜欢坐下来看书.多年过去,他已经收集了 N 本书 (1 <= N <= 100,000), 他想造一个新的书架来装所有书. 每本书 i ...
- p1848 [USACO12OPEN]书架Bookshelf
分析 单调队列优化dp即可 正确性显然,详见代码 代码 #include<bits/stdc++.h> using namespace std; #define int long long ...
- BZOJ5125 小Q的书架(决策单调性+动态规划+分治+树状数组)
设f[i][j]为前i个划成j段的最小代价,枚举上个划分点转移.容易想到这个dp有决策单调性,感性证明一下比较显然.如果用单调栈维护决策就不太能快速的求出逆序对个数了,改为使用分治,移动端点时树状数组 ...
- CF321E Ciel and Gondolas 【决策单调性dp】
题目链接 CF321E 题解 题意:将\(n\)个人分成\(K\)段,每段的人两两之间产生代价,求最小代价和 容易设\(f[k][i]\)表示前\(i\)个人分成\(k\)段的最小代价和 设\(val ...
- [BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)
第一种方法是决策单调性优化DP. 决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优. 根号函数是一个典型的具有决策单调性的函数,由 ...
- Codeforces 868F. Yet Another Minimization Problem【决策单调性优化DP】【分治】【莫队】
LINK 题目大意 给你一个序列分成k段 每一段的代价是满足\((a_i=a_j)\)的无序数对\((i,j)\)的个数 求最小的代价 思路 首先有一个暴力dp的思路是\(dp_{i,k}=min(d ...
- [loj6039]「雅礼集训 2017 Day5」珠宝 dp+决策单调性+分治
https://loj.ac/problem/6039 我们设dp[i][j]表示考虑所有价值小于等于i的物品,带了j块钱的最大吸引力. 对于ci相同的物品,我们一定是从大到小选k个物品,又发现最大的 ...
随机推荐
- 嵌入式开发之davinci--- 8148 中dsp在dsp_drv.c中的processdata()加算法出现下边缘条纹问题
(1)问题原因 dsp在alglink_priv.c中做灰度处理发现,下面出现条纹,后面发现是cache 缓存没及时写进内存问题 (2)解决办法 for(frameId=0; frameId<f ...
- Thinking in Java -- 类型信息RTTI
Thinking in Java – 类型信息 个人感觉 java 中的比較难的部分了,在看了些netty源代码发现事实上这块很实用. 这章重点是RTTI和反射.先说下自己的理解 RTTI是执行时识别 ...
- 【bzoj2809】[Apio2012]dispatching (左偏树)
我们需要枚举根,然后从其子树内选尽量多的点,薪水不超过M,可是暴力复杂度不对.于是考虑自下而上合并树(开始每棵树内只有一个节点,就是自己) 每个树是一个堆,我们维护树的节点个数和薪水总和,合并时,不断 ...
- C项目实践--图书管理系统(4)
前面已经把图书管理系统的所有功能模块都已实现完毕了,下面通过运行来分析该系统的操作流程并检验是否符合逻辑设计要求. 3.系统操作过程 F5 运行 1.登录系统 系统运行之后,提示输入用户名和密码,系统 ...
- debian repository的成长过程
1 基本概念 1.1 健康的安装 在端系统中的一次健康的安装指的是,在安装的包的集合中,所有的依赖都满足,并且没有冲突存在. 这的健康的安装是相对于端系统而言的,并不是相对于整个repo而言的.对整个 ...
- XMU 1613 刘备闯三国之三顾茅庐(一) 【并查集】
1613: 刘备闯三国之三顾茅庐(一) Time Limit: 1000 MS Memory Limit: 128 MBSubmit: 99 Solved: 29[Submit][Status][ ...
- lmbench andlmbench 移植测试
/*********************************************************************** * lmbench andlmbench 移植测试 * ...
- hdu5396(区间DP)
题目意思: 给定一个表达式,运算符没有优先级,求不同顺序计算,所有可能的得到的结果之和. 由于运算符没有优先级,所以有多种顺序去计算,设d[i][j]表示[i,j]区间表达式通过不同顺序计算,所以可能 ...
- Properties 文件的简单操作
properties 文件里面主要 存 一个Key对应一个Value 一般用来存放账户密码资料 方法有:Properties p=new Properties(); p.setproperty(& ...
- UVa 1363 Joseph's Problem (数论)
题意:给定 n,k,求 while(i <=n) k % i的和. 析:很明显是一个数论题,写几个样例你会发现规律,假设 p = k / i.那么k mod i = k - p*i,如果 k ...