BZOJ1233 [Usaco2009Open]干草堆tower[贪心+单调队列优化]
注意思路!多看几遍!
很巧妙的一道题。不再是决策点以dp值中一部分含j项为维护对象,而是通过维护条件来获取决策。
首先有个贪心策略,让底层的宽度尽可能小,才能让高度尽可能高。所以应该倒着dp,表示堆$i$~$n$的最高高度$f[i]$,同时这种最值应来源于之后的j,要在设一个$g[i]$表示以i为底层,最窄的宽度。这个的话真的只可意会啊。注意$g[i]$没人告诉你是单调的,$g[i]$之后一个不合法的决策都可能有$g[j]>g[i]$,所以单调性问题还当谨慎考虑。
所以dp方程就能出来了
$g[i]=min(sum[j-1]-sum[i-1]) $ $ g[j]<=sum[j-1]-sum[i-1]$
$f[i]=f[j]+1$
然后这个是$O(n^2)$的,考虑优化。从min内可以看出,j越小越好。那瓶颈就在于后面的那个约束条件怎么用,就是我在保证条件的情况下取j最小。
转化条件:$g[j]<=sum[j-1]-sum[i-1]$移项得$sum[j-1]-g[j]≥sum[i-1]$,而$sum[i-1]$是单调减的,那我要之前的j得插入$sum[j-1]-g[j]$,在dp到i时去把决策中大于等于$sum[i-1]$的找一个最小j。
于是单调队列维护j单调递减,$sum[j-1]-g[j]$单调减元素。假设dp完i后,我将目前i要向单调队列队尾比较。如果$sum[j-1]-g[j]>=sum[q[r]-1]-g[q[r]]$也就是j可以发挥与队尾同等的作用(甚至更优)的话,而我又渴求j尽可能小,那队尾就没什么卵用可以弹出了。直到不满足上述比较,就在队尾插入。这样保证$sum[j-1]-g[j]$单调减,我要取合法决策,便是队列头开始的一段大于等于$sum_i$的。注意,我要j最小,那队头满足条件的若干个决策,只要j最小的,那我可以依据j单调性将队头不断pop(反正之后$sum[i-1]$只会更小,现在留着也没用),直到最后一个满足条件的,就是最小的j。还是有点难以理解,贴个图。

然后每次就可以取到最小满足条件j了。
这个故事告诉我们单调队列的队头并不就一定是检查队头合法性的(范围之类的),也可以排除不优决策,这依赖于队头和队头下一个元素间的相互比较,要结合单调性予以考虑。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,:;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,:;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=+;
int sum[N],f[N],g[N],q[N];
int n,l,r; int main(){//freopen("test.in","r",stdin);//freopen("tmp.out","w",stdout);
read(n);for(register int i=;i<=n;++i)sum[i]=read(sum[i])+sum[i-];
l=,r=;q[l]=n+;
for(register int i=n;i;--i){
while(l<r&&sum[q[l+]-]-g[q[l+]]>=sum[i-])++l;
g[i]=sum[q[l]-]-sum[i-],f[i]=f[q[l]]+;
while(l<=r&&sum[q[r]-]-g[q[r]]<=sum[i-]-g[i])--r;
q[++r]=i;
}
printf("%d\n",f[]);
return ;
}
BZOJ1233 [Usaco2009Open]干草堆tower[贪心+单调队列优化]的更多相关文章
- BZOJ1233 [Usaco2009Open]干草堆tower 【单调队列优化dp】
题目链接 BZOJ1233 题解 有一个贪心策略:同样的干草集合,底长小的一定不比底长大的矮 设\(f[i]\)表示\(i...N\)形成的干草堆的最小底长,同时用\(g[i]\)记录此时的高度 那么 ...
- 【BZOJ 1233】 [Usaco2009Open]干草堆tower (单调队列优化DP)
1233: [Usaco2009Open]干草堆tower Description 奶牛们讨厌黑暗. 为了调整牛棚顶的电灯的亮度,Bessie必须建一座干草堆使得她能够爬上去够到灯泡 .一共有N大包的 ...
- bzoj1233 [Usaco2009Open]干草堆tower 【单调队列dp】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1233 单调队列优化的第一题,搞了好久啊,跟一开始入手斜率优化时感觉差不多... 这一题想通了 ...
- bzoj1233[Usaco2009Open]干草堆tower 单调队列优化dp
1233: [Usaco2009Open]干草堆tower Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 983 Solved: 464[Submi ...
- bzoj1233: [Usaco2009Open]干草堆tower
Description 奶牛们讨厌黑暗. 为了调整牛棚顶的电灯的亮度,Bessie必须建一座干草堆使得她能够爬上去够到灯泡 .一共有N大包的干草(1<=N<=100000)(从1到N编号) ...
- BZOJ1233 [Usaco2009Open]干草堆tower 和 BZOJ3549 [ONTAK2010]Tower
题意 Problem 3549. -- [ONTAK2010]Tower 3549: [ONTAK2010]Tower Time Limit: 10 Sec Memory Limit: 64 MBS ...
- bzoj 1233: [Usaco2009Open]干草堆tower
1233: [Usaco2009Open]干草堆tower Description 奶牛们讨厌黑暗. 为了调整牛棚顶的电灯的亮度,Bessie必须建一座干草堆使得她能够爬上去够到灯泡 .一共有N大包的 ...
- USACO 2009 Open 干草塔 Tower of Hay(贪心+单调队列优化DP)
https://ac.nowcoder.com/acm/contest/1072/B Description 为了调整电灯亮度,贝西要用干草包堆出一座塔,然后爬到牛棚顶去把灯泡换掉.干草包会从传送带上 ...
- bzoj 1233: [Usaco2009Open]干草堆tower 【想法题】
首先这题的$n^3$的DP是比较好想的 $f[i][j]$表示用前$i$包干草 且最顶层为第$j+1$包到第$i$包 所能达到的最大高度 然而数据范围还是太大了 因此我们需要去想一想有没有什么单调性 ...
随机推荐
- WinRar制作安装包
这次研究了下WinRar制作程序安装包,我使用的是5.21版本. 选中要打包的文件,先压缩为RAR文件,然后双击打开文件 输入目录时可以选择前两项,输入绝对路径时,则为第三项. 配置解压前运行的解压后 ...
- 手写一个简单到SpirngMVC框架
spring对于java程序员来说,无疑就是吃饭到筷子.在每次编程工作到时候,我们几乎都离不开它,相信无论过去,还是现在或是未来到一段时间,它仍会扮演着重要到角色.自己对spring有一定的自我见解, ...
- IIS配置相关问题:Framework 4.5 在IIS 7.5中运行
<system.webServer> <validation validateIntegratedModeConfiguration="false" /&g ...
- myeclipse显示db-brower
myeclipse显示db-brower 这东西怎么调出来? windows->show view->other->db borwser
- 洛谷 P1268 树的重量 题解
题面 目的:求出树的各边长度 条件:每个节点之间最短路.整个图中不存在负边 我们可以每一次把一个点加入树内,求出这个点和已经构建好的树的边的长度: 这个长度抽象理解一下就是(dis[i][j]+dis ...
- HTML(下)
目录 HTML(下) form表单 表单功能 表单属性 <input>输入标签(文本框)(内联标签) <select>下拉列表标签(内联标签) <textarea> ...
- Java基础(那些习以为常缺不知道原理的地方)
一.基础 1.1 正确的使用equals方法 Object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals.如下代码 // 不能使用一个值为null的引用类型变量来调 ...
- MySQL主从延时这么长,要怎么优化?
MySQL主从复制,读写分离是互联网常见的数据库架构,该架构最令人诟病的地方就是,在数据量较大并发量较大的场景下,主从延时会比较严重. 为什么主从延时这么大? 答:MySQL使用单线程重放RelayL ...
- scala新版本学习(3)
1.REPL:读取->求值->打印->循环.Scala程序将输入的内容快速的编译成为字节码,然后字节码文件交给Java虚拟机进行执行. 2.val是值不可变,var值可变.在变量声明 ...
- python多线程、多进程、协程笔记
import threading import time import multiprocessing import asyncio movie_list = ['斗破.avi', '复仇者联盟.mp ...