木板墙问题

考古学家在人迹罕至的一块平地上发现了由一堆木板拼成的墙。
令人惊奇的是这些木板的宽度都相同!地下的部分都已腐烂,而地上的部分也有高有低,
甚至有的地方根本没有木板,所以考古学家决定带走面积最大的长方形回去研究。 输入: 首先是整数n(1
<=n<=100000),表示木板的块数。接下来是n个整数h1,...,hn, 其中0<=hi<=1000000000,它们按照从左到右的顺序表示木板的高度。每块木板的宽度都是1。 最后一个0表示程序的结束。 输出: 其中最大长方形的面积。
测试输入
3 2000 2000 2000
7 1 2 5 6 1 3 3
0
测试输出
6000
10

图示如下

思路:最优解的矩形区域的高度是由该矩形区域中所包含的最低的木板决定。我们可以遍历一遍数据,判断出哪一个木板作为基准木板(矩形高度),并分别左右扩展为矩形区域所得到的面积最大,这个面积就是最优解。然后这个问题的关键就变成了如何确定一块木板能向左(右)扩展多少个。

方法如下

以n[i][1]表示第i个木板作为基准木板时能向左扩展的个数。

如果左相邻的木板高度小于基准木板,则该方向能扩展0个。否则 n[i][1]+=n[i-1][1]+1,然后再以第(i-2-n[i-1][1])块木板作为当前基准木板的左相邻木板继续循环的判断,直到某一个相邻的木板高度小于基准木板就结束。

代码如下

#include<stdio.h>
long long n[100002][3];
long long max,sum;
char c;
int main()
{
    while(scanf("%lld",&sum)&&sum)
    {
        c=getchar();
        max=0;
        for(int i=1;i<=sum;i++)
        {
         scanf("%lld",&n[i][0]);
         n[i][1]=n[i][2]=0;
        }
        for(int i=2;i<=sum;i++)
        {
            if(n[i][0]>n[i-1][0])
            n[i][1]=0;
            else
            {
                int k=i-1-n[i-1][1]-1;
                while(k>0&&n[k][0]>=n[i][0])
                {
                    k=k-n[k][1]-1;
                }
                n[i][1]=i-k-1;
            }
        }
        for(int i=sum-1;i>=1;i--)
        {
            if(n[i][0]>n[i+1][0])
            n[i][2]=0;
            else
            {
                int k=i+1+n[i+1][2]+1;
                while(k<=sum&&n[k][0]>=n[i][0])
                {
                    k=k+n[k][2]+1;
                }
                n[i][2]=k-i-1;
            }
        }
        for(int i=1;i<=sum;i++)
        {
            if((n[i][1]+n[i][2]+1)*n[i][0]>max)
            max=(n[i][1]+n[i][2]+1)*n[i][0];
        }
        printf("%lld\n",max);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/xlink-stve/p/8859345.html

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值