zoukankan      html  css  js  c++  java
  • POJ2559-Largest Rectangle in a Histogram

    Largest Rectangle in a Histogram

    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 22077   Accepted: 7137


    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 integern, denoting the number of rectangles it is composed of. You may assume that1<=n<=100000. Then follown integersh1,...,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 is1. 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
    




    解题心得:

    1、其实这个题是动态规划加搜索,先说搜索部分,能够以某个柱形为中心形成公共矩形面积的,只有柱形左方和右方都高于它,所以将每一个柱形为中心向左向右搜索,但是这样毫无疑问会超时。所以需要在这个搜多的基础上优化。


    2、然后就是动态规划部分,首先我们可以使用一个right[]组记录一下这个这个柱形最左方的大于它的那个柱形的位置,用left[]数组记录一下最右方的柱形大于它的那位置。当它的下个柱形在搜索的时候,如果比左方的那个柱形高度小就,这个柱形的左右边界就可以直接调到左方的哪个柱形的左右边界再开始找。然后得到答案就行了。


    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+10;
    typedef long long ll;
    ll num[maxn];
    ll Right[maxn],Left[maxn];
    int main()
    {
        ll n;
        while(scanf("%lld",&n) && n)
        {
            memset(Right,0,sizeof(Right));
            memset(Left,0,sizeof(Left));
            
            Left[1] = 1;
            Right[n] = n;
            for(ll i=1;i<=n;i++)
                scanf("%lld",&num[i]);
                
            //找左方的从左方开始才能够动态规划
            for(ll i=2;i<=n;i++)
            {
                ll now = i;
                while(now >= 1 && num[i] <= num[now-1])
                    now = Left[now-1];
                Left[i] = now;
            }
    
            //找右方的就从右方开始
            for(ll i=n-1;i>=1;i--)
            {
                ll now = i;
                while(now <n && num[i] <= num[now+1])
                    now = Right[now+1];
                Right[i] = now;
            }
    
            //右减左加1就是该柱形为中心形成的最大的矩形块的长
            ll sum = 0,Max = 0;
            for(ll i=1;i<=n;i++)
            {
                sum = (Right[i] - Left[i] + 1) * num[i];
                if(sum > Max)
                    Max = sum;
            }
            printf("%lld
    ",Max);
        }
    }


  • 相关阅读:
    作为一名JAVA程序员应该有怎样的就业思维
    Html +++++css总结
    spring知识点全部复习
    Spring注解问题,[action中注入service失败
    VMware中Ubuntu18配置静态IP地址
    MySQL5.7修改登录密码的几种方式
    MySQL忘记root密码
    Windows安装Redis
    Java两个整数相除保留n位小数
    Java四舍五入保留n位小数的常用写法
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9107327.html
Copyright © 2011-2022 走看看