积木大赛

Description
积木大赛

(block.pas/c/cpp)

【问题描述】

春春幼儿园举办了一年一度的“积木大赛”。

在2013年NOIP大赛中,平平同学己经搭建了宽度为n的大厦,其中第i块高度为hi。今年比赛的内容是对其NOIP2013搭建大厦进行扩建,使用的材料也都是体积为1正方体积木。

今年搭建的规则是:如果要在某一个位置上放一个积木,必须满足它的左下、下方、右下都有积木(用二维坐标a表示,如果要在a[i,j]位置放积木,那么a[i-1,j-1]、a[i,j-1]、a[i+1,j-1]必须要有积木)。

如果搭的积木大厦越高,平平同学就会觉得越舒服,现有m个积木,问你能搭建的最大高度是多少?

【输入】

第一行两个用空格隔开的整数n和m,分别表示己搭好的宽度和可以使用的积木数量。

后面有n行,每行一个整数hi表示己搭建的第i列积木的高度。

【输出】

一个整数,表示能搭建的最大高度。

【输入输出样例】

样例1

样例2

block.in

block.out

block.in

block.out

8 4

3

4

2

1

3

3

2

4

5

3 100

3

3

3

4

【数据说明】

30%的数据满足:n<=10;m<=1000。

50%的数据满足:n<=100;m<=1000,000。

70%的数据满足:n<=1000;m<=10,000,000。

80%的数据满足:n<=10,000;m<=100,000,000。

100%的数据满足:n<=100,000;m<=1000,000,000, 1≤hi≤10^9。


算法一:对于50%的数据:

①从高到低枚举每一个高度看是否能达到, 时间复杂度O(n);

②对于每一个高度,枚举最高点在哪一列,时间复杂度O(n);

③从当前枚举的最高列往两边递减判断是否合法,时间复杂度O(n);

总时间复杂度O(n3)。(Hint: 实测暴力能拿75分, 根本就不用二分…)

算法二:对于70%的数据:

在算法一中的第二步求高度时,使用二分答案,时间复杂度降为O(logn)。总时间复杂度为O(n2logn)。

算法三:100%的数据:

对于第二步和第三步,根据单调性,我们用L[i]表示在高度为H时第I列达到高度H时最左端的位置,R[i]为最右端的位置。通过O(n)的时间得到L,R,总的时间复杂度为O(nlogn)
Hint: 单调队列维护, 实际上就是利用斜率. 和单调队列优化DP差不多.

你可能感兴趣的:(单调队列)