https://ac.nowcoder.com/acm/contest/1072/B

Description

为了调整电灯亮度,贝西要用干草包堆出一座塔,然后爬到牛棚顶去把灯泡换掉。干草包会从传送带上运来,共会出现N包干草,第i包干草的宽度是Wi,高度和长度统一为1。干草塔要从底层开始铺建。贝西会选择最先送来的若干包干草,堆在地上作为第一层,然后再把紧接着送来的几包干草包放在第二层,再铺建第三层……重复这个过程,一直到所有的干草全部用完。每层的干草包必须紧靠在一起,不出现缝隙,而且为了建筑稳定,上层干草的宽度不能超过下层的宽度。按顺序运来的干草包一定要都用上,不能将其中几个干草包弃置不用。贝西的目标是建一座最高的塔,请你来帮助她完成这个任务吧。

Input Format

第一行:单个整数:N,1 ≤ N ≤ 100000 第二行到N + 1行:第i + 1行有一个整数Wi,1 ≤ Wi ≤ 10000

Output Format

第一行:单个整数,表示可以建立的最高高度

Sample Input


Sample Output

 

Hint

将1 和2放在第一层,将3放在第二层

即前两个(宽度为1和2的)放在底层,总宽度为3,在第二层放置宽度为3的。

       +----------+

       |         |

       +---+------+

       |  |     |

       +---+------+

题解

from:题解报告

这题首先应该会想到贪心,但马上否定掉。但此时如果你完全放弃了贪心,那么你就很可能想不到正解了。

由于此题阶段明显,可以断定用动规。在不考虑数据范围的前提下应该是很好做的。但N ≤ 100000,只能寻求更好的算法。

再回想到贪心,这时会想到一个奇葩的感觉貌似是对的,又不知如何证明的推论:

将塔看作一个面积一定图形,要使其最高,必须最瘦。

事实上这个是正确的。证明引自张昆玮大牛

任意取出一个能使层数最高的方案,设有CA层,把其中从下往上每一层最大的块编号记为Ai;任取一个能使底边最短的方案,设有CB层,把其中从下往上每一层最大的块编号记为Bi。显然A1>=B1,ACB<=BCB,这说明至少存在一个k属于(1,CB),满足Ak-1>=Bk-1且Ak<=Bk。也就是说,方案 A 第K 层完全被方案 B 第K 层包含。构造一个新方案,第K 层往上按方案 A,往下按方案 B,两边都不要的块放中间当第K 层。新方案的层数与 A 相同,而底边长度与 B 相同。证毕。

加点解释:

现在有两座塔,一个高度最大,设为A,另一个「从低到高」顺序下,每层宽度尽量小,设为B(B的高度比A小)
首先,显然有 hB≤hA,并且 A 最底层宽度不比 B 小
因为 hB≤hA,所以肯定在某一层 A 比 B 宽度要小(A 全程比 B 宽的情况是不可能出现的,除非 A 比 B 多了几块积木),也一定存在一层,此时刚好 B 用的比 A 多
所以就把 B 刚好用的比 A 多的那一层之上的部分,换成 A 的,显然会更细一些,并且高度也和 A 一样

所以,只要存在比「宽度最小塔」更高的,就可以按照如上操作替换,最后就会发现,「宽度最小塔」就是最高的那一个

(什么,看不懂?慢慢看吧。。耐心点就看懂了,想当初我也是如此熬过来的)

所以我们可以用f[i]表示i到n这些干草能堆成的最大高度,g[i]表示最底层的最短宽度。
f[i]=f[j]+1,g[i]=w[j-1,i] (j>=i,w[j-1,i]>=g[j])

要尽量取最小的j

但是如果直接暴力转移的化时间复杂度是O(n2)的不足以胜任这个数据范围,明显过不了,要进行优化。

我们发现在阶段i时,对于k>j>i,j会比k优,决策为k的情况只能是J不满足条件而k满足条件,整理方程得 f[j] - sum[j - 1] > f[k]-sum[k - 1]

观察转移方程可以发现在满足转移条件的情况下,j越大则f[i]、g[i]都更优,故此可以用单调队列优化转移:把j存进队列中,若队头元素的下一位满足转移条件则把队头踢出,每次入队时如果队尾比要入队的元素还要晚满足条件则把队尾删除,每次转移时直接取队头进行转移。

于是底边最短的方案,层数最高。枚举最底层由哪几块组成,由此可以得出一个方程:从n到i中最底层的宽度f[i]=min(sum[j-1...i]) 满足 f[j]<=sum[j-1...i](因为这样会使得上一层的宽度不大于下一层的宽度) 且 n>=j>i

其中i=n->1

分析一下,发现f[i]=min(sum[j-1])-sum[i-1](令sum[i]表示宽度的前缀和),而sum[i]是随i的增大而增大的,所以从i到n一旦发现一个符合条件的决策j,便将其取出来更新f[i]。但是这仍不能通过所有数据。

再次分析,发现所有的决策的值(例如对于决策j值即为sum[j-1])由n往前都是单调递减的,也就是一个比一个优。因此决定性的因素则是他们的生效时间。

对于决策j:观察不等式f[j]<=sum[j-1...i]即f[j]<=sum[j-1]-sum[i-1],变形可得sum[i-1]<=sum[j-1]-f[j],发现sum[j-1]-f[j]便是其生效时间,也就是说在第一个i使得sum[i-1]<=sum[j-1]-f[j]之后到1决策j都是有效的。于是我们可以开一个单调队列,使得生效时间递减,并且队头始终生效并且队头+1未生效。由于后入队的决策比前面的优,于是一旦队头+1生效,队头便可弹掉。入队的时候,如果发现队尾-1的生效时间<队尾的生效时间,则弹掉队尾-1。

如此一来便完美的解决了此题,复杂度为O(n)

 #include <cstdio>
const int N=+;
int q[N],g[N],f[N],sum[N],w[N],n;
int main()
{
scanf("%d",&n);
for (int i=;i<=n;++i) {
scanf("%d",w+i);
sum[i]=sum[i-]+w[i];
}
q[]=n+;
int h=,t=;
for (int i=n;i;--i) {
while (h<t && f[q[h+]]<=sum[q[h+]-]-sum[i-]) ++h;
f[i]=sum[q[h]-]-sum[i-];
g[i]=g[q[h]]+;
q[++t]=i;
while ((t>h) && (f[q[t-]]-sum[q[t-]-]+sum[q[t]-]>f[q[t]]))
--t,q[t]=q[t+];
}
printf("%d\n",g[]);
}

USACO 2009 Open 干草塔 Tower of Hay(贪心+单调队列优化DP)的更多相关文章

  1. USACO 2009 Open 干草塔 Tower of Hay

    USACO 2009 Open 干草塔 Tower of Hay Description 为了调整电灯亮度,贝西要用干草包堆出一座塔,然后爬到牛棚顶去把灯泡换掉.干草 包会从传送带上运来,共会出现N包 ...

  2. BZOJ1233 [Usaco2009Open]干草堆tower 【单调队列优化dp】

    题目链接 BZOJ1233 题解 有一个贪心策略:同样的干草集合,底长小的一定不比底长大的矮 设\(f[i]\)表示\(i...N\)形成的干草堆的最小底长,同时用\(g[i]\)记录此时的高度 那么 ...

  3. 【BZOJ 1233】 [Usaco2009Open]干草堆tower (单调队列优化DP)

    1233: [Usaco2009Open]干草堆tower Description 奶牛们讨厌黑暗. 为了调整牛棚顶的电灯的亮度,Bessie必须建一座干草堆使得她能够爬上去够到灯泡 .一共有N大包的 ...

  4. bzoj1233[Usaco2009Open]干草堆tower 单调队列优化dp

    1233: [Usaco2009Open]干草堆tower Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 983  Solved: 464[Submi ...

  5. BZOJ1233 干草堆 - 单调队列优化DP

    问题描述: 若有干个干草, 分别有各自的宽度, 要求将它们按顺序摆放, 并且每层的宽度不大于 它的下面一层 ,  求最多叠几层 题解: zkw神牛证明了: 底边最短, 层数最高         证明: ...

  6. BZOJ 1233 干草堆 (单调队列优化DP)

    $ BZOJ~1233~~ $ 干草堆: (题目特殊性质) $ solution: $ 很妙的一道题目,开始看了一眼觉得是个傻逼贪心,从后往前当前层能多短就多短,尽量节省花费.但是这是DP专题,怎么会 ...

  7. BZOJ1233 [Usaco2009Open]干草堆tower[贪心+单调队列优化]

    地址 注意思路!多看几遍! 很巧妙的一道题.不再是决策点以dp值中一部分含j项为维护对象,而是通过维护条件来获取决策. 首先有个贪心策略,让底层的宽度尽可能小,才能让高度尽可能高.所以应该倒着dp,表 ...

  8. bzoj1233 [Usaco2009Open]干草堆tower 【单调队列dp】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1233 单调队列优化的第一题,搞了好久啊,跟一开始入手斜率优化时感觉差不多... 这一题想通了 ...

  9. [USACO09Open] Tower of Hay 干草塔

    为了调整电灯亮度,贝西要用干草包堆出一座塔,然后爬到牛棚顶去把灯泡换掉.干草包会从传送带上运来,共会出现N包干草,第i包干草的宽度是W i ,高度和长度统一为1.干草塔要从底层开始铺建.贝西会选择最先 ...

随机推荐

  1. web系统能力培养计划

    服务器知识掌握如下 01购买linux服务器 客户端工具:https://mobaxterm.mobatek.net/download.html 02linux常用命令 https://www.run ...

  2. Sequence Models Week 1 Building a recurrent neural network - step by step

    Building your Recurrent Neural Network - Step by Step Welcome to Course 5's first assignment! In thi ...

  3. CSS样式实现两个图片平分三角

    <div class='pageOption'> <a href='#' class='option' > <img src='http://imgsrc.hubbles ...

  4. JZOJ-2019-11-7 A组

    T1 Input 从文件 awesome.in 中读入数据. 第一行 2 个用空格隔开的整数 \(n\), \(P\). 第二行 n 个用空格隔开的整数 \(A_1, \cdots , A_n\). ...

  5. Arduino学习——u8glib库资料整理

    第一部分,u8glib标准语法格式: 本文使用的是DFRobot出品的LCD12864 Shield V1.0 端口占用情况: SPI Com: SCK = 13, MOSI = 11, CS = 1 ...

  6. WEB测试方法总结-笔记

    此文来自公开课培训笔记!!! 一.输入框 1.字符型输入框: (1)字符型输入框:英文全角.英文半角.数字.空或者空格.特殊字符“~!@#¥%……&*?[]{}”特别要注意单引号和&符 ...

  7. k8s中解决容器时差问题

    解决k8s的pod容器的时差常用的两种方式: 1.通过设置pod 模板中的环境变量 env解决 在pod的模板中添加以下: apiVersion: v1 kind: Podmetadata:   na ...

  8. 一维消消乐(DP)

    一维消消乐是一款非常简单的游戏.有n颗珠子排成一排,每一颗珠子有一个价值w(可能是负数). 游戏是这样,你可以选择如若干对相邻的珠子,让他们同时消去.每一对珠子的消失,都会使得总分数加上两颗珠子相乘的 ...

  9. 吴裕雄--天生自然MySQL学习笔记:MySQL LIKE 子句

    在 MySQL 中使用 SQL SELECT 命令来读取数据, 同时我们可以在 SELECT 语句中使用 WHERE 子句来获取指定的记录. WHERE 子句中可以使用等号 = 来设定获取数据的条件, ...

  10. 汪慧和201771010123《面向对象程序设计(Java)》第三周学习总结

    1.实验目的与要求 (1)进一步掌握Eclipse集成开发环境下java程序开发基本步骤: (2)熟悉PTA平台线上测试环境: (3)掌握Java语言构造基本程序语法知识(ch1-ch3): (4)利 ...