51nod 1519 拆方块

51nod 1519 拆方块

有n堆方块,第i堆方块由hi个方块堆积而成。具体可以看样例。
接下来拆方块。一个方块称为内部方块当且仅当他的上下左右都是方块或者是地面。否则方块就是边界方块。每一次操作都要把边界方块拿掉。
问多少次操作之后所有方块会消失。
样例解释:
这里写图片描述

每一次操作,边界方块被标记为红色。
经过第一次操作,只剩下四个方块。第二次操作之后,只剩下一个方块。

对于这个题目,我们把一个方块被拆下来的原因分成两种。

  
  
更一般的,我们从新定义外部方块。
那么,一列方块被消去的最少操作次数,等于:
L[i]R[i] 分别表示,第i列,以第一种和第二种消去的最少次数,H[i]为第i列原始方块的数量。
当某一列的左侧没有方块时,则这一列最多再进行一次操作即:

L[i+1]L[i]<=1

当某一列的右侧没有方块时,则这一列最多再进行一次操作即:

R[i]R[i+1]<=1

当某一侧的操作次数超过了这一列的方块数量,则有:

L[i]=H[i]R[i]=H[i]

综上:

L[i]={H[i]           ,    H[i]<=L[i1]L[i1]+1   ,   H[i]>L[i1]

R[i]={H[i]           ,    H[i]<=R[i+1]R[i+1]+1   ,   H[i]>R[i+1]

所以:

answer=MAXni=1(min(L[i],R[i]))

下面是AC代码

#include <stdio.h>
#include <algorithm>
using namespace std;
int L[100005],R[100005],H[100005];
int main ()
{
    int n;
    scanf("%d",&n);
    n++;
    for(int i=1;i<n;i++)    scanf("%d",H+i);
    for(int i=1;i<n;i++)
    {
        L[i]=L[i-1]+1;
        if(L[i]>H[i])   L[i]=H[i];
    }
    for(int i=n-1;i;i--)
    {
        R[i]=R[i+1]+1;
        if(R[i]>H[i])   R[i]=H[i];
    }
    int ans=0;
    for(int i=1;i<n;i++)
        ans=max(ans,min(L[i],R[i]));
    printf("%d\n",ans);
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值