[BZOJ1233][Usaco2009Open]干草堆tower(单调队列优化)
传送门
题意搞skr人…,其实就是堆方块:
有n(n<=100000)个干草,每堆有个宽度,现在要且分成若干段,把每一段的干草按顺序堆起来形成一个多层的干草堆(所以下标越小的干草堆放在越下面)且宽度要逐层非严格递减(上面一层的宽度<=下面一层的宽度),求最多可以放多少层。
好神啊这题。。
题意看起来不复杂,所以我们很容易想到一个贪心:
从上往下倒着考虑,假设我们已经知道上面一层的宽度为w,那么下面一层的最优的策略一定是的大于等于w的宽度和中最靠近w的。
想出贪心之后我们需要证明他的正确性,但是也可以证明贪心是错的:
在bzoj该题的Discuss下id为thy的大佬已经举出了一个例子证明贪心是错的:
ex:
16
6 1 1 1 6 1 1 1 1 6 1 1 1 1 1 6
贪心:
6
111116
111161116
最优:
6111
1161
1116
1116
为什么是错的呢?
因为第i层可以帮第i+1层分担一些宽度,使得i+2层压力更小
但是我们可以在证明贪心是错误的过程中模糊地猜到一个结论:
假如该问题的一个解是最优解,那么它的最底层宽度一定最小。
这个结论有没有用我们现在还不知道,但是zory左老师有言:
每一个题目肯定有每一个题目的特质,肯定要抓住这个特质来解题。
为啥,因为最底层最小可以让干草堆叠的尽量的高嘛…
然后我们往dp去想,设列一个初级dp方程:
设f[i][j]f[i][j]f[i][j]表示用前i包干草,且当前层用的是第j包到第i包所能达到的最大高度。
则f[i][j]=max{f[j−1][k]}+1(sum[i]−sum[j−1]≤sum[j−1]−sum[k−1],k<j≤i)f[i][j]=max\lbrace f[j-1][k]\rbrace+1(sum[i]-sum[j-1] \leq sum[j-1]-sum[k-1],k<j\leq i)f[i][j]=max{f[j−1][k]}+1(sum[i]−sum[j−1]≤sum[j−1]−sum[k−1],k<j≤i)
我们发现这个方程的时间复杂度为O(N3)O(N^3)O(N3),空间复杂度为O(N2)O(N^2)O(N2),实在是太太太大了。
我们尝试优化这个方程,但是我们发现无法优化时空都到O(N)O(N)O(N)的级别。这时候我们从结论入手,设列一个新的dp方程,且可以优化到O(N)O(N)O(N)级别。
结合贪心的思路尝试倒推:
设
f[i]f[i]f[i]为用i~n来构成的干草堆,底层最短是多少
g[i]g[i]g[i]表示状态f[i]的最大高度
则
f[i]=min{sum[j−1]−sum[i−1]}(i<j≤n,f[j]≤sum[j−1]−sum[i−1])f[i]=min\lbrace sum[j-1]-sum[i-1]\rbrace(i<j\leq n,\ \ \ f[j] \leq sum[j-1]-sum[i-1])f[i]=min{sum[j−1]−sum[i−1]}(i<j≤n, f[j]≤sum[j−1]−sum[i−1])
g[i]=g[j]+1g[i]=g[j]+1g[i]=g[j]+1
由于sum[i]具有单调性,所以我们从单调性开始着手使用单调队列优化d的套路:
在转移方程中可以得到:
f[i]f[i]f[i]从较小的jjj转移过来会更优秀,所以符合条件的jjj越小越好 —(1)
然后在判断式中可以看到:
f[j]≤sum[j−1]−sum[i−1]f[j] \leq sum[j-1]-sum[i-1]f[j]≤sum[j−1]−sum[i−1]
移项,把关于iii,jjj的分别移到两边
sum[i−1]≤sum[j−1]−f[j]sum[i-1] \leq sum[j-1]-f[j]sum[i−1]≤sum[j−1]−f[j]
那么我们又可以得到:
对于状态i的当前决策jjj,sum[j−1]−f[j]sum[j−1]−f[j]sum[j−1]−f[j]越大 ,可以作为决策的情况就越多,这样的j越有用。—(2)
所以我们有了两个分别关于下标和式子的单调条件(1)和(2)
所以我们设两个决策jjj,kkk满足k>jk>jk>j,且sum[k−1]−f[k]≤sum[j−1]−jf[j]sum[k-1]-f[k] \leq sum[j-1]-jf[j]sum[k−1]−f[k]≤sum[j−1]−jf[j]的话,k就是无用状态可以删去。
用单调队列维护即可,注意由于我们是倒推所以单调队列的head和tail要反过来(因为我们默认head<=tail)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
typedef long long ll;
const int N=1e5+10;
int a[N],sum[N];
int list[N],head,tail;
int f[N],g[N];
int main()
{int n;scanf("%d",&n);sum[0]=0;for(int i=1;i<=n;i++){scanf("%d",&a[i]);sum[i]=sum[i-1]+a[i];}list[1]=n+1; head=tail=1; //注意由于倒序所以head和tail反过来 for(int i=n;i>=0;i--){while(head<tail && f[list[head+1]]<=sum[list[head+1]-1]-sum[i-1]) head++;int j=list[head];f[i]=sum[j-1]-sum[i-1];g[i]=g[j]+1;while(head<=tail && sum[i-1]-f[i]>=sum[list[tail]-1]-f[list[tail]]) tail--;list[++tail]=i;}printf("%d\n",g[1]);return 0;
}
[BZOJ1233][Usaco2009Open]干草堆tower(单调队列优化)相关推荐
- bzoj-1233 [Usaco2009Open]干草堆tower
1233: [Usaco2009Open]干草堆tower** 题目链接 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1030 Solved: 49 ...
- Bzoj1233 [Usaco2009Open]干草堆tower
Time Limit: 10 Sec Memory Limit: 162 MB Submit: 811 Solved: 378 Description 奶牛们讨厌黑暗. 为了调整牛棚顶的电灯的亮度 ...
- bzoj 1233: [Usaco2009Open]干草堆tower【dp+单调栈】
参考:https://www.cnblogs.com/N-C-Derek/archive/2012/07/11/usaco_09_open_tower.html 虽然长得很像斜率优化,但是应该不算-- ...
- [bzoj1233]干草堆tower
[bzoj1233]干草堆tower 首先,倒着直接贪心是会被卡的 数据如下: 6 11 10 7 3 2 6 然后我们可以发现一些性质:每个点取能取的最小的宽度,这样一定能构成最优解 然后状态是f[ ...
- bzoj 1233 干草堆tower 优先队列优化dp
https://www.lydsy.com/JudgeOnline/problem.php?id=1233 描述: 奶牛们讨厌黑暗. 为了调整牛棚顶的电灯的亮度,Bessie必须建一座干草堆使得她能够 ...
- 算法笔记--单调队列优化dp
单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...
- 多重背包单调队列优化思路_多重背包之单调队列优化理论性总结
多重背包之单调队列优化: 若用F[j]表示对容量为j的背包,处理完前i种物品后,背包内物品可达到的最大总价值,并记m = min(n, j / v).放入背包的第i种物品的数目可以是:0.1.2--, ...
- tyvj1305 最大子序和 【单调队列优化dp】
描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7 当m=2或m=3时,S=5+1=6 输 ...
- poj 2373(单调队列优化dp)
在长为L(<=1000000)的草地(可看成线段)上装喷水头,喷射是以这个喷水头为中心,喷水头的喷洒半径是可调节的调节范围为[a,b].要求草地的每个点被且只被一个喷水头覆盖,并且有些连续区间必 ...
最新文章
- 记mac电脑下pycharm配置qt-creator开发环境
- MVC4做网站后台:栏目管理1、添加栏目
- scikit-learn——快速入门 - daniel-D(转)
- Cortex-M系列处理器指令集区别详解
- 《高级着色语言HLSL入门》系列文章
- Python爬虫系列(一)——手把手教你写Python爬虫
- C#winform【在状态栏显示实时时间】--实战练习一
- EAS 后台事务配置
- wm8978 控制接口,
- 《Spring Boot极简教程》附录2 编程的本质
- SqlServer的填充因子
- 【观察】星环科技“七剑下天山”,做数据世界超高速引擎
- Doris报错there is no scanNode Backend
- 浏览器标签中显示京东logo
- 《网络基础学习之三》认识网线制作工具
- 风格迁移1-02:Liquid Warping GAN(Impersonator)-源码模型测试-报错解决
- 【openh264】libfreerdp 编解码 CQP VBR
- Deep learning based segmentation for automated training of apple trees on trellis wires
- 微凉日子,菠菜鸡丝面
- [CS229学习笔记] 5.判别学习算法与生成学习算法,高斯判别分析,朴素贝叶斯,垃圾邮件分类,拉普拉斯平滑