Description

当农夫约翰闲的没事干的时候,他喜欢坐下来看书。多年过去,他已经收集了 N 本书 (1 <= N <= 100,000), 他想造一个新的书架来装所有书。
每本书 i 都有宽度 W(i) 和高度 H(i)。书需要按顺序添加到一组书架上;比如说,第一层架子应该包含书籍1 ... k,第二层架子应该以第k + 1本书开始,以下如此。每层架子的总宽度最大为L(1≤L≤1,000,000,000)。每层的高度等于该层上最高的书的高度,并且整个书架的高度是所有层的高度的总和,因为它们都垂直堆叠。
请帮助农夫约翰计算整个书架的最小可能高度。
有N(1 <= N <= 100000)本书,每本书有一个宽度W(i),高度H(i),(1 <= H(i) <= 1,000,000; 1 <= W(i) <= L)。
现在有足够多的书架,书架宽度最多是L (1 <= L <= 1,000,000,000),把书按顺序(先放1,再放2.....)放入书架。某个书架的高度是该书架中所放的最高的书的高度。
将所有书放入书架后,求所有书架的高度和的最小值?

solution

弄了好久啊,首先这个DP没法维护啊,最后弄出一个暴力均摊的线段树做法.
\(f[i]=f[j]+v[j+1][i]\),这是原DP方程,\(v[j][i]\)表示\(j-i\)间的最大值.
考虑优化:
我们在线段树中,分别维护 \(f[j]\) 和 \(v[j]\),单调指针扫描,扫到 \(i\) 时,用 \(H[i]\) 取更新 \([1,i-1]\) 的 \(v\) 值.
再维护一个\(f[j]+v[j]\),那么转移就是线段树查最值了.
关键在于修改的复杂度:
维护一个区间最小值和区间最大值:
1.如果最小值大于 \(H[i]\),那么没有修改的必要,直接返回
2.如果最大值小于 \(H[i]\),那么直接打上覆盖标记即可
复杂度的证明:
一个无单调性的序列经过一次暴力修改之后,就会变成单调递增或递减序列了,那么下一次修改就会只会选择其中一部分进行修改(因为另一部分总会碰到上述两个剪枝中的一种情况),并且修改完之后依旧是满足单调性的,所以除了第一次修改之外,之后就是线段树修改的复杂度了,均摊 \(O(n*logn)\),常数有些大

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define ls (o<<1)
#define rs (o<<1|1)
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=100005;const ll inf=1e15;
int n,m,v[N],lazy[N<<2],mx[N<<2],mn[N<<2];ll f[N<<2],a[N],g[N<<2];
inline void upd(RG int o){f[o]=Min(f[ls],f[rs]);mx[o]=Max(mx[ls],mx[rs]);mn[o]=Min(mn[ls],mn[rs]);
}
inline void pushdown(RG int o){if(!lazy[o])return ;int k=lazy[o];f[ls]=g[ls]+k;mx[ls]=k;mn[ls]=k;f[rs]=g[rs]+k;mx[rs]=k;mn[rs]=k;lazy[ls]=k;lazy[rs]=k;lazy[o]=0;
}
inline void Modify(int l,int r,int o,int sa,int se,int t){if(l!=r)pushdown(o);if(mn[o]>=t)return ;if(sa<=l && r<=se){if(mx[o]<t){lazy[o]=t;f[o]=g[o]+t;mx[o]=mn[o]=t;return ;}}if(l==r)return ;int mid=(l+r)>>1;if(se<=mid)Modify(l,mid,ls,sa,se,t);else if(sa>mid)Modify(mid+1,r,rs,sa,se,t);else Modify(l,mid,ls,sa,mid,t),Modify(mid+1,r,rs,mid+1,se,t);upd(o);
}
inline void updata(int l,int r,int o,int sa,ll t){if(l==r){g[o]=t;return ;}int mid=(l+r)>>1;pushdown(o);if(sa<=mid)updata(l,mid,ls,sa,t);else updata(mid+1,r,rs,sa,t);g[o]=Min(g[ls],g[rs]);
}
inline ll qry(int l,int r,int o,int sa,int se){if(l!=r)pushdown(o);if(sa<=l && r<=se)return f[o];int mid=(l+r)>>1;ll ret,q1,q2;if(se<=mid)ret=qry(l,mid,ls,sa,se);else if(sa>mid)ret=qry(mid+1,r,rs,sa,se);else{q1=qry(l,mid,ls,sa,mid),q2=qry(mid+1,r,rs,mid+1,se);ret=Min(q1,q2);}upd(o);return ret;
}
int l=0;
void work()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d%lld",&v[i],&a[i]),a[i]+=a[i-1];ll tmp;for(int i=1;i<=n;i++){while(l<i && a[i]-a[l]>m)l++;Modify(0,n,1,0,i-1,v[i]);tmp=qry(0,n,1,l,i-1);if(i!=n)updata(0,n,1,i,tmp);}cout<<tmp<<endl;
}int main()
{freopen("pp.in","r",stdin);freopen("pp.out","w",stdout);work();return 0;
}

转载于:https://www.cnblogs.com/Yuzao/p/8098136.html

[USACO12OPEN]书架Bookshelf相关推荐

  1. 洛谷P1848 [USACO12OPEN]书架Bookshelf

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

  2. 书架 bookshelf

    书架 bookshelf 书架 bookshelf 题目描述 当Farmer John闲下来的时候,他喜欢坐下来读一本好书. 多年来,他已经收集了N本书 (1 <= N <= 100,00 ...

  3. 书架bookshelf

    第一题 书架 [问题描述] 为了方便同学们查阅资料,程序设计兴趣小组的辅导老师打算将积攒了很多年的n本书放到上课教室的书架上去. 教室的书架是一层一层叠起来的,每一层最多可以放m本书.每一层的高度由放 ...

  4. [慈溪2012]书架(bookshelf)

    题目描述 为了方便同学们查阅资料,程序设计兴趣小组的辅导老师打算将积攒了很多年的n本书放到上课教室的书架上去. 教室的书架是一层一层叠起来的,每一层最多可以放m本书.每一层的高度由放在这层中最高的那本 ...

  5. python3爬小说_python3小说爬虫

    作为一个很喜欢看书的人,有时候在网页上看小说,会被数不胜数的广告弄的很烦,刚好最近在研究python,就自己写了一个小说爬虫,并用pyqt做了图形界面. 下面介绍一下主要思路,不过就不开源了,因为我的 ...

  6. 每日学一个设计模式1——迭代器模式

    引言 精通设计模式是从码农脱颖而出的条件之一.跟着<图解设计模式>这本书学习设计模式,从今天开始,一天总结一个设计模式. 迭代器模式(一个一个遍历) 用处 隐藏遍历集合的内部结构,遍历不同 ...

  7. 我的世界常用命令和物品名称

    显示玩家坐标: /gamerule showcoordinates true 是显示玩家坐标的指令 区域填充: /fill 坐标 坐标 物品 物品大全: https://minecraft.52pk. ...

  8. python爬虫小说系统_python3小说爬虫

    作为一个很喜欢看书的人,有时候在网页上看小说,会被数不胜数的广告弄的很烦,刚好最近在研究python,就自己写了一个小说爬虫,并用pyqt做了图形界面. 下面介绍一下主要思路,不过就不开源了,因为我的 ...

  9. P1848 [USACO12OPEN]Bookshelf G(线段树优化 DP)

    P1848 [USACO12OPEN]Bookshelf G 有nnn间物品,每个物品有两个属性Wi,HiW_i, H_iWi​,Hi​,宽度跟高度,要求把这nnn件物品划分成若干连续的组,每组内∑W ...

最新文章

  1. 计算机硬件的作用论文,计算机硬件的作用论文.doc
  2. 工程是.java文件_1.8 工程相关解析(各种文件,资源访问)
  3. Linux内核链表的移植与使用
  4. https抓包_从Wireshark抓包看HTTPS的加密功能
  5. [MySQL FAQ]系列 -- 账号密码包含反斜线时怎么办
  6. C++ 接口 函数导出_Matlab与C/C++混合编程、Visual C++与Matlab封装库互相调用相关要点...
  7. 排列和组合、以及数列(五)
  8. python 3d重建_三维人脸重建(一)——Python读取obj文件
  9. jQuery常用的查找Dom元素方法
  10. php魔法函数用途,PHP中的Magic Methods (魔术函数)
  11. 设计模式在游戏中的应用--模板方法(七)
  12. DM8整合java的jpa框架(附整合源码)
  13. MoleBox PRO build 2.3.054,, Latest , Private Member Build Edition
  14. 学习Axure RP原型设计
  15. php 失去焦点,jquery设置焦点方法focus()和jquery失去焦点方法blur()
  16. windows10如何关闭cortana
  17. 大数据的学习总结(2)--大数据基础知识
  18. 知物由学 | APP大瘦身,新一代AAB框架下的安全加固之道
  19. 【Linux】Linux目录
  20. 通过API获取ip地址以及城市和运营商

热门文章

  1. mysql开启 pscache_Druid连接池在mysql的场景PS Cache是否需要开启?
  2. pycharm下的第一个函数程序
  3. 数据挖掘实践(金融风控)——task5:模型融合
  4. 2019斯坦福CS224n深度学习自然语言处理笔记(3)反向传播与计算图
  5. php validate验证用户,PHP validate 数据验证demo
  6. FLOPs衡量模型复杂度
  7. 如何安装inf类型驱动程序 inno
  8. MySQL自增主键删除后重复问题
  9. Cocos2dx 下面,对 音乐 和音效简单封装
  10. python学习:Python 包