积木大赛
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差不多.