51nod 1519 拆方块

来源:互联网 发布:电脑文件数据恢复 编辑:程序博客网 时间:2024/06/05 01:13

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;}
原创粉丝点击