传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=138

传送门2:http://www.lydsy.com/JudgeOnline/problem.php?id=2678

最开始没看到要将那些书按顺序放!!一定是按顺序!我还以为是自己安排那个书架,白费了我好久时间。

然而看对题之后仍然不会。。。

令f(i)表示前i本书已经放到书架上,且第i本是某个书架的最后一本的最小高度和,则

f(i) = min { f(j) + max { h[j + 1], h[j + 2]....., h[i] } }, 其中w[i + 1] + w[i + 2] + ... + w[j] <= L.

裸的是O(N^2)的(好像Silver版本的这一题就是O(N^2)可以过),所以需要优化。(又是dp优化!每次看dp优化少说都要2个钟头,烦)

显然,f(j)随j的增大而增大(非严格增大,即大于等于),而对于不变的i,max { h[j + 1], h[j + 2]....., h[i] } 随j的增大而减小(非严格减小,即小于等于),因此我们可以把i前面的所有j,按照max { h[j + 1], h[j + 2]....., h[i] }的大小来分块,把这个值相等的j分到一块去,那么对于这一块j,显然取最前面那个最好,因为根据刚刚所说,f(j)随j的增大而增大(非严格增大,即大于等于)。然而有很多块,那么应该取那一块的最前面那个呢?我们应该用一个平衡树(multiset,就是STL set的可以重复元素版本)把所有可以取的值存起来,并在dp过程中不停地删除那些不能取的值,并添加新的可以取的值。具体见代码。

#include <cstdio>
#include <set> const int maxn = 100005; int n, ttttttttt[maxn], num, *tail = ttttttttt;
long long L, s[maxn], h[maxn], f[maxn];
std::multiset<long long> val; int main(void) {
freopen("bookshelf.in", "r", stdin);
freopen("bookshelf.out", "w", stdout);
scanf("%d%I64d", &n, &L);
for (int i = 1; i <= n; ++i) {
scanf("%I64d%I64d", h + i, s + i);
s[i] += s[i - 1];
} // num表示现在拥有块的个数, tail[i]表示第i个块的结尾位置,
// 注意tail是一个指针,这是有方便之处的,之后就会看到
for (int i = 1; i <= n; ++i) {
// 下面是将第i本书考虑进去后,重新更新分块
while (num && h[i] >= h[tail[num]]) {
val.erase(val.find(f[tail[num - 1]] + h[tail[num]]));
--num;
}
tail[++num] = i;
val.insert(f[tail[num - 1]] + h[i]); // tail[0]应该表示的是合法的j使得前缀和s[i] - s[j] <= L
// 当 > L时,就应该erase掉对应的值,然后++tail[0],但如果
// 下一个就是这个块的结尾了,就要指针移动啦,因为这个块整
// 个都被删除了,然后再--num
while (s[i] - s[tail[0]] > L) {
val.erase(val.find(f[tail[0]] + h[tail[1]]));
if (tail[0] + 1 == tail[1]) {
++tail;
--num;
}
else {
val.insert(f[tail[0] + 1] + h[tail[1]]);
++tail[0];
}
} f[i] = *val.begin();
}
printf("%I64d\n", f[n]);
return 0;
}

官方题解是记录了一个块有多大,我是记录了这个快的结尾位置,都一样。

[USACO 2012 Open Gold] Bookshelf【优化dp】的更多相关文章

  1. 【bzoj2591】[Usaco 2012 Feb]Nearby Cows 树形dp

    题目描述 Farmer John has noticed that his cows often move between nearby fields. Taking this into accoun ...

  2. [USACO 2012 Mar Gold] Large Banner

    传送门:http://www.usaco.org/index.php?page=viewproblem2&cpid=127 又是一道这种题目,遇到一次跪一次,这次终于硬着头皮看懂了题解,但是谢 ...

  3. [USACO 2012 Feb Gold] Cow Coupons【贪心 堆】

    传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=118 传送门2:http://www.lydsy.com/JudgeOn ...

  4. bzoj258 [USACO 2012 Jan Gold] Bovine Alliance【巧妙】

    传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=111 传送门2:http://www.lydsy.com/JudgeOn ...

  5. bzoj2581 [USACO 2012 Jan Gold] Cow Run【And-Or Tree】

    传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=110 传送门2:http://www.lydsy.com/JudgeOn ...

  6. [USACO 2018 Feb Gold] Tutorial

    Link: USACO 2018 Feb Gold 传送门 A: $dp[i][j][k]$表示前$i$个中有$j$个0且末位为$k$的最优解 状态数$O(n^3)$ #include <bit ...

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

    2021.12.08 P1848 [USACO12OPEN]Bookshelf G(线段树优化DP) https://www.luogu.com.cn/problem/P1848 题意: 当农夫约翰闲 ...

  8. [USACO 2018 Jan Gold] Tutorial

    Link: USACO 2018 Jan Gold 传送门 A: 对于不同的$k$,发现限制就是小于$k$的边不能走 那么此时的答案就是由大于等于$k$的边形成的图中$v$所在的连通块除去$v$的大小 ...

  9. [USACO 2017 Dec Gold] Tutorial

    Link: USACO 2017 Dec Gold 传送门 A: 为了保证复杂度明显是从终结点往回退 结果一开始全在想优化建边$dfs$……其实可以不用建边直接$multiset$找可行边跑$bfs$ ...

随机推荐

  1. weblogic集群的资料

    博客分类: weblogic 其实网上关于weblogic集群的资料非常多[大部分都是从创建新的domain开始,我这篇先介绍怎么样把原本普通的domain改造为集群环境],如果觉得不够,可以啃web ...

  2. python字符串连接方法效率比较

    方法1:直接通过加号(+)操作符连接 1 website = 'python' + 'tab' + '.com' 方法2:join方法 1 2 listStr = ['python', 'tab',  ...

  3. 2016.3.15__H5页面实战__第七天

    假设您认为这篇文章还不错,能够去H5专题介绍中查看很多其它相关文章. 个人简书地址: dhttp://www.jianshu.com/users/5a2fd0b8fb30/latest_article ...

  4. Android拍照、摄像方向旋转的问题 代码具体解释

    近期做了个拍照.摄像的应用.遇到了拍照.摄像的图像相对于现实.翻转了90度.原因:相机这个硬件的角度是横屏的角度,所以会出现都是横屏的. 1.照相.摄影预览图像的正确角度显 示: public sta ...

  5. 【机器学习具体解释】SVM解二分类,多分类,及后验概率输出

    转载请注明出处:http://blog.csdn.net/luoshixian099/article/details/51073885 CSDN−勿在浮沙筑高台 支持向量机(Support Vecto ...

  6. Oracle学习(18)【DBA向】:分布式数据库

    分布式数据库 什么是分布数据库? l数据物理上被存放在网络的多个节点上,逻辑上是一个总体. 分布式数据库的独立性 l分布数据的独立性指用户不必关心数据怎样切割和存储,仅仅需关心他须要什么数据. Ora ...

  7. linux-shell脚本命令之awk

    [ awk简单介绍: ] awk能够从一个文本中获取部分内容, 或者对这个文本进行排版, 使它按某种格式输出. [ awk工作流程: ] awk会把文件一行内容去到内存里, 然后对这行内容进行分段 ( ...

  8. 强连通分量+poj2186

    强连通分量:两个点能够互相连通. 算法分解:第一步.正向dfs全部顶点,并后序遍历 第二步,将边反向,从最大边dfs,构成强连通分量 标号最大的节点属于DAG头部,cmp存一个强连通分量的拓扑序. p ...

  9. [IT学习]学习Python过程需要记忆的一些坑

    1.列表的引用和复制 A byte of Python 中文4.05c版本85页 单纯对列表进行引用,则列表指向同一对象. 如果你需要复制一份全新的拷贝,则需要通过切片操作. 2.仅有一个元素的元组, ...

  10. asp.net mvc + javascript生成下载文件

    近期做的是对现有项目进行重构.WEB FROM改成MVC,其实也算是推倒重来了. 里面有一个导出功能,将数据输出成txt文件,供下载.原先的做法是有一个隐藏的iframe,在这个iframe的页面中设 ...