[USACO 2012 Open Gold] Bookshelf【优化dp】
传送门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】的更多相关文章
- 【bzoj2591】[Usaco 2012 Feb]Nearby Cows 树形dp
题目描述 Farmer John has noticed that his cows often move between nearby fields. Taking this into accoun ...
- [USACO 2012 Mar Gold] Large Banner
传送门:http://www.usaco.org/index.php?page=viewproblem2&cpid=127 又是一道这种题目,遇到一次跪一次,这次终于硬着头皮看懂了题解,但是谢 ...
- [USACO 2012 Feb Gold] Cow Coupons【贪心 堆】
传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=118 传送门2:http://www.lydsy.com/JudgeOn ...
- bzoj258 [USACO 2012 Jan Gold] Bovine Alliance【巧妙】
传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=111 传送门2:http://www.lydsy.com/JudgeOn ...
- 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 ...
- [USACO 2018 Feb Gold] Tutorial
Link: USACO 2018 Feb Gold 传送门 A: $dp[i][j][k]$表示前$i$个中有$j$个0且末位为$k$的最优解 状态数$O(n^3)$ #include <bit ...
- 2021.12.08 P1848 [USACO12OPEN]Bookshelf G(线段树优化DP)
2021.12.08 P1848 [USACO12OPEN]Bookshelf G(线段树优化DP) https://www.luogu.com.cn/problem/P1848 题意: 当农夫约翰闲 ...
- [USACO 2018 Jan Gold] Tutorial
Link: USACO 2018 Jan Gold 传送门 A: 对于不同的$k$,发现限制就是小于$k$的边不能走 那么此时的答案就是由大于等于$k$的边形成的图中$v$所在的连通块除去$v$的大小 ...
- [USACO 2017 Dec Gold] Tutorial
Link: USACO 2017 Dec Gold 传送门 A: 为了保证复杂度明显是从终结点往回退 结果一开始全在想优化建边$dfs$……其实可以不用建边直接$multiset$找可行边跑$bfs$ ...
随机推荐
- java quartz的使用,做时间轮询调用 CronTrigger
import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionExceptio ...
- POJ 1284 Primitive Roots (求原根个数)
Primitive Roots 题目链接:id=1284">http://poj.org/problem?id=1284 利用定理:素数 P 的原根的个数为euler(p - 1) t ...
- How to Uninstall Internet Explorer 11 for Windows 7
Internet Explorer 11 is the newest version of Microsoft's web browser, but not everyone is a fan. If ...
- Angular团队公布路线图,并演示怎样与React Native集成
本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2015/06/angular-2-react-native-roadmap 前不久在旧 ...
- win8系统 如何不显示这台电脑的文件夹
在win8系统中,默认有下面这种文件夹 只要打开注册表编辑器,找到下面所示的项目,删除所有子文件夹即可(最后剩下一个DelegateFolders不用管) [HKEY_LOCAL_MACHINE\ ...
- js和jquery实现回到顶层
js <!DOCTYPE html> <html> <head> <title>返回顶部</title> <style> bod ...
- 6 JobApp默认视图开发
第一步:引入angularjs 添加app模块 现在我们正式进入开发,下面是我们在上一节建立的目录结构: 我们需要再src路径下,新建index.html文件,先引入angularjs文件: < ...
- 使用 C# 开发智能手机软件:推箱子(三)
这是"使用 C# 开发智能手机软件:推箱子"系列文章的第三篇.在这篇文章中,介绍 Common/Block.cs 源程序文件. 1 namespace Skyiv.Ben.Pu ...
- C项目实践--图书管理系统(4)
前面已经把图书管理系统的所有功能模块都已实现完毕了,下面通过运行来分析该系统的操作流程并检验是否符合逻辑设计要求. 3.系统操作过程 F5 运行 1.登录系统 系统运行之后,提示输入用户名和密码,系统 ...
- Entity Framework底层操作封装V2版本号(3)
如今是附加的,组合查询须要的扩展类.大家知道lanmda表达式的组合条件比較麻烦,所以就加了一样一个类,方便进行组合查询: using System; using System.Collections ...