HDU1506 Largest Rectangle in a Histogram (动规)

Largest Rectangle in a Histogram

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10873    Accepted Submission(s): 2969



Problem Description
A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles:

Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.
 

Input
The input contains several test cases. Each test case describes a histogram and starts with an integer n, denoting the number of rectangles it is composed of. You may assume that 1 <= n <= 100000. Then follow n integers h1, ..., hn, where 0 <= hi <= 1000000000. These numbers denote the heights of the rectangles of the histogram in left-to-right order. The width of each rectangle is 1. A zero follows the input for the last test case.
 

Output
For each test case output on a single line the area of the largest rectangle in the specified histogram. Remember that this rectangle must be aligned at the common base line.
 

Sample Input
  
  
7 2 1 4 5 1 3 3 4 1000 1000 1000 1000 0
 

Sample Output
  
  
8 4000
 

Source
 

Recommend
LL   |   We have carefully selected several similar problems for you:   1505  1058  1176  2870  2571

题目大意:给你一张柱形图,先给你一个N表示柱的数量,然后给你N个高度,每一个柱的宽度是1,让你在柱形图中放入一个矩形,要求输出的矩形面积是最大的。

解题思路:矩形的高度一定是那些给出柱的高度中的一个, 以一个柱的高度为矩形的高时计算出当前这个高度下最大的矩形面积, 枚举每一个高度,最后找到那个最大的,
就是 所求。所以题目就变成了 在给定高度下找矩形的最大宽度(高度一定找最大面积),那么就要找到 当前高度的左右边界,明显 只要旁边的柱比这个高度要高就可以再向旁
边扩展一个单位,解题思路给出。
还好这题没出负数数据,要不然就完蛋了。。。
#include <iostream>
using namespace std;
#define M 100005
__int64 l[M],r[M],vis[M];               //数据用int过不去,所以用__int64.
__int64 max(__int64 x,__int64 y){
    return x>y?x:y;
}
int min(int x,int y){
    return x<y?x:y;
}
__int64 DP(__int64 a[],__int64 n){
    __int64 i;
    for(i=1;i<=n;i++)                //从左边找左边界,从右边开始找会超时,不解释。
    {    
        while(a[i]<=a[l[i]-1])    l[i]=l[l[i]-1];     //如果左边的比当前高度高,说明可以向左边扩展,while这里有点递归的味道,
                                                      //直到左边比当前高度低,才结束while。
    }
    for(i=n;i>=1;i--)
    {   
        while(a[i]<=a[r[i]+1])    r[i]=r[r[i]+1];     //找右边界的过程和找左边界过程一样。
    }
    __int64 tot=0;  
    for(i=1;i<=n;i++)                                 //每一个高度的最大宽度已经找到,计算最大面积。
    {
        tot=max(tot,(r[i]-l[i]+1)*a[i]);              //宽度为1,所以还要+1.
    }
    return tot;
}

int main(__int64 i,__int64 j,__int64 k)
{
    __int64 n,cur;
    while(scanf("%I64d",&n)!=EOF&&n)
    {  l[0]=l[n+1]=vis[0]=vis[n+1]=-1;               //这里是防一些特殊的数据,按理来说取0就可以了,不过过不了。
       r[n+1]=n;                                     
        for(i=1;i<=n;i++)
        { 
            l[i]=r[i]=i;                             //l[i]记录的是vis[i]的左边界,r[i]记录vis[i]的右边界。
            scanf("%I64d",&vis[i]);
        }
        cur=DP(vis,n);
        printf("%I64d\n",cur);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值