1. 程式人生 > >POJ 2559 Largest Rectangle in a Histogram (棧的運用)

POJ 2559 Largest Rectangle in a Histogram (棧的運用)

cst 所有 left cal turn nta 分享 ons hist

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

Hint

Huge input, scanf is recommended. 分析:題目的數據很大,要求這個最大的面積,我們想到可能要預處理某些方面. 那麽我們可以用L[i]表示從右往左找到的第一個j(j<i,且h[j]<h[i)]; 並且用R[i]表示從左往右找到的第一個j(j>i,且h[j]<h[i]) 那麽枚舉所有i的 (R[i]-L[i]-1)*h[i]的最大值即為結果 用找L[i]舉例,我們可以用棧進行處理,i的編號從1開始取 對於數據 7 2 1 4 5 1 3 3 L[1]=0 將1加入棧中 {1}; a[2]<a[1] 將1彈出 棧中無元素 故L[2]=0,再將2加入棧中{2} a[3]>a[2] L[3]=2,將3加入棧中{2,3}; a[4]>a[3] L[4]=3,將4加入棧中{2,3,4}; a[5]<a[4] 將4彈出; a[5]<a[3] 將3彈出; a[5]<a[2] 將2彈出;此時棧為空 L[5]=0; 將5加入{5}; …… 棧始終從棧頂到棧底,儲存數列從大到小,從右到左的值,這樣就總能找到在某個區域左邊的第一個小於它的位置. 找R[i]的方法相似. 代碼如下:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <map>
#include <algorithm>
#include <stack>
using namespace std;
typedef long long ll;
const int MAXN=1e5+10;
ll a[MAXN];
ll L[MAXN];
ll R[MAXN];
int main()
{

      int n;
      ll maxx;
      while(scanf("%d",&n)!=EOF&&n)
      {
          maxx=0;
             stack<ll>S;
            for(int i=1;i<=n;i++)
                scanf("%lld",&a[i]);
           L[1]=0;
           S.push(1);
            for(ll i=2;i<=n;i++)
           {
             while(!S.empty()&&a[S.top()]>=a[i])
              S.pop();
              if(S.empty())
                L[i]=0;
              else
              {
            //      cout<<" "<<S.top()<<endl;
                L[i]=S.top();
              }
            //  printf("%d\n",L[i]);
              S.push(i);
           }
           while(!S.empty())
            S.pop();
         R[n]=n+1;
           S.push(n);
           for(int i=n-1;i>=1;i--)
           {
             while(!S.empty()&&a[S.top()]>=a[i])
                S.pop();
             if(S.empty())
              R[i]=n+1;
             else
             {
                R[i]=S.top();
             }
              S.push(i);
           }
          for(int i=1;i<=n;i++)
           {
              maxx=max(maxx,(R[i]-L[i]-1)*a[i]);
           }
           printf("%lld\n",maxx);
      }

    return 0;
}

POJ 2559 Largest Rectangle in a Histogram (棧的運用)