传送门

题意搞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&lt;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&lt;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&lt;j≤n,f[j]≤sum[j−1]−sum[i−1])f[i]=min\lbrace sum[j-1]-sum[i-1]\rbrace(i&lt;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&gt;jk&gt;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(单调队列优化)相关推荐

  1. bzoj-1233 [Usaco2009Open]干草堆tower

    1233: [Usaco2009Open]干草堆tower** 题目链接 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1030 Solved: 49 ...

  2. Bzoj1233 [Usaco2009Open]干草堆tower

    Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 811  Solved: 378 Description 奶牛们讨厌黑暗. 为了调整牛棚顶的电灯的亮度 ...

  3. bzoj 1233: [Usaco2009Open]干草堆tower【dp+单调栈】

    参考:https://www.cnblogs.com/N-C-Derek/archive/2012/07/11/usaco_09_open_tower.html 虽然长得很像斜率优化,但是应该不算-- ...

  4. [bzoj1233]干草堆tower

    [bzoj1233]干草堆tower 首先,倒着直接贪心是会被卡的 数据如下: 6 11 10 7 3 2 6 然后我们可以发现一些性质:每个点取能取的最小的宽度,这样一定能构成最优解 然后状态是f[ ...

  5. bzoj 1233 干草堆tower 优先队列优化dp

    https://www.lydsy.com/JudgeOnline/problem.php?id=1233 描述: 奶牛们讨厌黑暗. 为了调整牛棚顶的电灯的亮度,Bessie必须建一座干草堆使得她能够 ...

  6. 算法笔记--单调队列优化dp

    单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...

  7. 多重背包单调队列优化思路_多重背包之单调队列优化理论性总结

    多重背包之单调队列优化: 若用F[j]表示对容量为j的背包,处理完前i种物品后,背包内物品可达到的最大总价值,并记m = min(n, j / v).放入背包的第i种物品的数目可以是:0.1.2--, ...

  8. 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 输 ...

  9. poj 2373(单调队列优化dp)

    在长为L(<=1000000)的草地(可看成线段)上装喷水头,喷射是以这个喷水头为中心,喷水头的喷洒半径是可调节的调节范围为[a,b].要求草地的每个点被且只被一个喷水头覆盖,并且有些连续区间必 ...

最新文章

  1. 记mac电脑下pycharm配置qt-creator开发环境
  2. MVC4做网站后台:栏目管理1、添加栏目
  3. scikit-learn——快速入门 - daniel-D(转)
  4. Cortex-M系列处理器指令集区别详解
  5. 《高级着色语言HLSL入门》系列文章
  6. Python爬虫系列(一)——手把手教你写Python爬虫
  7. C#winform【在状态栏显示实时时间】--实战练习一
  8. EAS 后台事务配置
  9. wm8978 控制接口,
  10. 《Spring Boot极简教程》附录2 编程的本质
  11. SqlServer的填充因子
  12. 【观察】星环科技“七剑下天山”,做数据世界超高速引擎
  13. Doris报错there is no scanNode Backend
  14. 浏览器标签中显示京东logo
  15. 《网络基础学习之三》认识网线制作工具
  16. 风格迁移1-02:Liquid Warping GAN(Impersonator)-源码模型测试-报错解决
  17. 【openh264】libfreerdp 编解码 CQP VBR
  18. Deep learning based segmentation for automated training of apple trees on trellis wires
  19. 微凉日子,菠菜鸡丝面
  20. [CS229学习笔记] 5.判别学习算法与生成学习算法,高斯判别分析,朴素贝叶斯,垃圾邮件分类,拉普拉斯平滑

热门文章

  1. 【前端】PS图层切图
  2. python语言迷宫游戏_一个Python迷宫小游戏
  3. 无人值守u盘安装linux,U盘无人值守安装Linux操作系统
  4. 专访Dan Kohn:阡陌交迭,云原生布局开源生态构建及深度应用
  5. Python之Lock锁
  6. 程序员的自我进化:学习之道,如何更有效的学习
  7. Angular2+ 属性绑定
  8. 微信小程序消息订阅超详细流程步骤
  9. qgis面图层周长面积计算(视频)
  10. 校招----深信服测试笔经面经