【CodeForces - 574D】Bear and Blocks (dp,思维)

版权声明:欢迎学习我的博客,希望ACM的发展越来越好~ https://blog.csdn.net/qq_41289920/article/details/82776756

题干:

Limak is a little bear who loves to play. Today he is playing by destroying block towers. He built n towers in a row. The i-th tower is made of hi identical blocks. For clarification see picture for the first sample.

Limak will repeat the following operation till everything is destroyed.

Block is called internal if it has all four neighbors, i.e. it has each side (top, left, down and right) adjacent to other block or to the floor. Otherwise, block is boundary. In one operation Limak destroys all boundary blocks. His paws are very fast and he destroys all those blocks at the same time.

Limak is ready to start. You task is to count how many operations will it take him to destroy all towers.

Input

The first line contains single integer n (1 ≤ n ≤ 105).

The second line contains n space-separated integers h1, h2, ..., hn (1 ≤ hi ≤ 109) — sizes of towers.

Output

Print the number of operations needed to destroy all towers.

Examples

Input

6
2 1 4 6 2 2

Output

3

Input

7
3 3 3 1 3 3 3

Output

2

Note

The picture below shows all three operations for the first sample test. Each time boundary blocks are marked with red color.

After first operation there are four blocks left and only one remains after second operation. This last block is destroyed in third operation.

题目大意:

给你一个长度为N的一串序列,ai表示在这个位子上有一座高度为ai的木块。

每次操作需要去掉所有这样的木块:

一个木块如果上下左右有一个空白位子。

问一共需要操作几次,使得整个序列变成空的。

解题报告:

    其实也可以直接i分别从2和n-1开始,然后初始化的时候把dpl[1]和dpr[n]给初始化了。

    dp是真的难想啊!!有的题解说转化为一个匹配最长递增序列的题目,但我感觉还是用dp更方便理解一些。

    dpl[i]表示从左边开始消除把第i列消完所需的最小时间,dpr表示从右边开始消除的。很明显可以看出来,我要销毁第i列的格子,只有三种方法,要么是左边是空的,要么是右边是空的,要么就是从最顶上一层一层转化过来,也就是用a[i]的时间。只有这三种状态下才可以一次转移到这一个状态,也就是第i列全部被清空,那么我们现在要维护这个最小值,然后再遍历每一个定点,取一个最大值,因为我们需要把所有的盒子都清空,所以我们需要取一个最大值,这个值就是最终的答案。

AC代码:

#include<bits/stdc++.h>

using namespace std;
const int MAX = 1e5 + 5;
int a[MAX];
int dpl[MAX],dpr[MAX];
int main()
{
	int n;
	cin>>n;
	for(int i = 1; i<=n; i++) scanf("%d",a+i);
	dpl[0] = 0;dpr[n+1] = 0;
	for(int i = 1; i<=n; i++) dpl[i] = min(dpl[i-1] + 1, a[i]);
	for(int i = n; i>=1; i--) dpr[i] = min(dpr[i+1] + 1, a[i]);
	int ans = 0;
	for(int i = 1; i<=n; i++) {
		ans = max(ans,min(dpl[i],dpr[i]));
	}
	cout << ans << endl;
	return 0 ;
 } 

猜你喜欢

转载自blog.csdn.net/qq_41289920/article/details/82776756