题目链接: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+决策单调性的更多相关文章

  1. [BZOJ2739]最远点(DP+分治+决策单调性)

    根据旋转卡壳,当逆时针遍历点时,相应的最远点也逆时针转动,满足决策单调性.于是倍长成链,分治优化DP即可,复杂度O(n^2). #include<cstdio> #include<a ...

  2. luogu P1721 [NOI2016]国王饮水记 斜率优化dp 贪心 决策单调性

    LINK:国王饮水记 看起来很不可做的样子. 但实际上还是需要先考虑贪心. 当k==1的时候 只有一次操作机会.显然可以把那些比第一个位置小的都给扔掉. 然后可以得知剩下序列中的最大值一定会被选择. ...

  3. [USACO12OPEN]书架Bookshelf

    Description 当农夫约翰闲的没事干的时候,他喜欢坐下来看书.多年过去,他已经收集了 N 本书 (1 <= N <= 100,000), 他想造一个新的书架来装所有书. 每本书 i ...

  4. p1848 [USACO12OPEN]书架Bookshelf

    分析 单调队列优化dp即可 正确性显然,详见代码 代码 #include<bits/stdc++.h> using namespace std; #define int long long ...

  5. BZOJ5125 小Q的书架(决策单调性+动态规划+分治+树状数组)

    设f[i][j]为前i个划成j段的最小代价,枚举上个划分点转移.容易想到这个dp有决策单调性,感性证明一下比较显然.如果用单调栈维护决策就不太能快速的求出逆序对个数了,改为使用分治,移动端点时树状数组 ...

  6. CF321E Ciel and Gondolas 【决策单调性dp】

    题目链接 CF321E 题解 题意:将\(n\)个人分成\(K\)段,每段的人两两之间产生代价,求最小代价和 容易设\(f[k][i]\)表示前\(i\)个人分成\(k\)段的最小代价和 设\(val ...

  7. [BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)

    第一种方法是决策单调性优化DP. 决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优. 根号函数是一个典型的具有决策单调性的函数,由 ...

  8. Codeforces 868F. Yet Another Minimization Problem【决策单调性优化DP】【分治】【莫队】

    LINK 题目大意 给你一个序列分成k段 每一段的代价是满足\((a_i=a_j)\)的无序数对\((i,j)\)的个数 求最小的代价 思路 首先有一个暴力dp的思路是\(dp_{i,k}=min(d ...

  9. [loj6039]「雅礼集训 2017 Day5」珠宝 dp+决策单调性+分治

    https://loj.ac/problem/6039 我们设dp[i][j]表示考虑所有价值小于等于i的物品,带了j块钱的最大吸引力. 对于ci相同的物品,我们一定是从大到小选k个物品,又发现最大的 ...

随机推荐

  1. java类载入器——ClassLoader

    Java的设计初衷是主要面向嵌入式领域,对于自己定义的一些类,考虑使用依需求载入原则.即在程序使用到时才载入类,节省内存消耗,这时就可以通过类载入器来动态载入. 假设你平时仅仅是做web开发,那应该非 ...

  2. Axure安装fontawesome字体

    http://www.fontawesome.com.cn/ 下载后,双击安装字体提示  不是有效的字体,百度 ..解决方法: 任务管理器--服务-- MpsSvc-Windows Firewall ...

  3. ES6 模块化(Module)export和import详解 export default

    ES6 模块化(Module)export和import详解 - CSDN博客 https://blog.csdn.net/pcaxb/article/details/53670097 微信小程序笔记 ...

  4. solr 7.2.1 单机及伪集群启动

    1.solr的下载: 下载地址:solr官网:http://lucene.apache.org/solr进入官网点击download或者点击链接https://lucene.apache.org/so ...

  5. mysql11---主键普通全文索引

    .1主键索引添加 当一张表,把某个列设为主键的时候,则该列就是主键索引 create table aaa (id int unsigned primary key auto_increment , n ...

  6. HDU2389 Rain on your Parade —— 二分图最大匹配 HK算法

    题目链接:https://vjudge.net/problem/HDU-2389 Rain on your Parade Time Limit: 6000/3000 MS (Java/Others)  ...

  7. YTU 2897: E--外星人供给站

    2897: E--外星人供给站 时间限制: 2 Sec  内存限制: 128 MB 提交: 20  解决: 13 题目描述 外星人指的是地球以外的智慧生命.外星人长的是不是与地球上的人一样并不重要,但 ...

  8. 一步一步学Silverlight 2系列(3):界面布局

    述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  9. python 判断是否为有效域名

    import re pattern = re.compile( r'^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|' r'([a-zA-Z]{1}[0-9]{1}) ...

  10. I.MX6 查找占用UART进程

    /**************************************************************************** * I.MX6 查找占用UART进程 * 说 ...