/*
這題的題目比較難讀懂,其實就是給定座標系上一系列相鄰的矩形,高度不等,求把這些矩形連起來看
能夠得到的最大矩形的面積.這題我一開始想到的是需要用堆棧來往後處理,但是一直想不出來Discuss
裏面說的O(N)的算法,再加上昨天又是09年最後一天,實在沒心情搞下去了.今天早上睡了個懶覺,起來
狀態不錯,一下就想出了O(N)的算法,要想達到O(N)必須對矩形進行合併.具體思路如下:
(1)設置一個堆棧用來矩形.遇到比上一個矩形高度高的新矩形就入棧
(2)如果遇到比上一個矩形高度低的矩形就要進行出棧合併以及最大矩形面積計算的處理.假設當前新
矩形的高和寬分別爲curh, curw, 利用totalw統計出棧的矩形的寬度和,然後一直進行出棧操作,每出
棧一個矩形就將其寬度加到totalw上,統計將其高度乘以totalw與maxsize比較進行更新.出棧矩形的
高度乘以totalw表示的是以這個矩形的高爲大矩形的高可以得到的最大矩形面積.出棧操作一直進行
到棧頂矩形的高度小於等於新矩形的高度.
最後將新矩形的高度以及totalw + curw作爲一個新的元素壓入棧中.這樣就完成了這種情況下對新矩形
的操作
(3)最後棧中還有一些列的矩形,這些矩形構成了一個高度非降序的矩形序列.然後再進行一邊出棧處理就
可以了.可以參考圖示分析.
這題整體並不難,但是確是一道非常好的題,考察對堆棧的應用以及對合並方法達到線性複雜度的理解
*/
圖1:
圖2:
圖3:
#include <iostream>
#define MAX_N 50005
#define maxv(a, b) ((a) >= (b) ? (a) : (b))
using namespace std;
struct elem
{
int h, w;
}stack[MAX_N];
int top, n, maxSize;
int main()
{
int curw, curh, i, lasth;
while(scanf("%d", &n) && n != -1)
{
top = lasth = maxSize = 0;
int totalw , cursize;
for(i = 1; i <= n; i++)
{
scanf("%d%d", &curw, &curh);
if(curh >= lasth)
{
stack[top].h = curh;
stack[top].w = curw;
top++;
}
else
{
totalw = cursize = 0;
while(top != 0)
{
if(stack[top - 1].h > curh)
{
totalw += stack[top - 1].w;
if((cursize = totalw * stack[top - 1].h) > maxSize)
maxSize = cursize;
top -= 1;
}
else break;
}
totalw += curw;
stack[top].h = curh;
stack[top].w = totalw;
top++;
}
lasth = curh;
}
totalw = cursize = 0;
while(top != 0)
{
totalw += stack[top - 1].w;
if((cursize = totalw * stack[top - 1].h) > maxSize)
maxSize = cursize;
top--;
}
printf("%d/n", maxSize);
}
return 0;
}