您的位置:首页 > 其它

poj 2559求柱形图中最大矩形

2014-05-08 00:16 267 查看
两种解法,其中一种是用单调栈。

我想到的是另外一种:最大的矩形,中间一定有个最矮的某个单位矩形,所以求出每个包含矩形histogram[i]的最大矩形的面积,输出这些面积中最大那个即可。

key:用两个数组记录histogram[i]左右两边第一个比它小的单位矩形的序号leftLowerId[i]和rightLowerId[i],那么对于histogram[i],它自己的最大矩形面积就是(rightLowerId[i] - leftLowerId[i] - 1) *  histogram[i]。

  这里找leftLowerId和rightLowerId的时候用DP加速。以rightLowerId为例,找到右边比histogram[i]矮的矩形,停止,遇到比histogram[i]高的矩形j,直接跳到比histogram[j]矮的矩形rightLowerId[j].

#include<iostream>
using namespace std;

//the histogram stored from left to right
long histogram[100001];
int rightLowerId[100001];
int leftLowerId[100001];

//from right to left
void FindRightSideLowerRec(int n)
{
rightLowerId[n - 1] = n; // there is no rectangle on its right
for (int i = n - 2; i >= 0; i--){

int cid = i + 1;
while (histogram[cid] >= histogram[i] && cid < n){
cid = rightLowerId[cid]; // the key
}

rightLowerId[i] = cid;
}
}

//from left to right
void FindLeftSideLowerRec(int n)
{
leftLowerId[0] = -1; // there is no rectangle on its left
for (int i = 1; i < n; i++){

int cid = i - 1;
while (histogram[cid] >= histogram[i] && cid > -1){
cid = leftLowerId[cid]; // the key
}

leftLowerId[i] = cid;
}
}

long long CalLargestRectangle(int n)
{
long long largestArea = 0;

for (int i = 0; i < n; i++)
{
long long width = rightLowerId[i] - leftLowerId[i] - 1;
long long height = histogram[i];

long long area = width * height;

if (area > largestArea)
largestArea = area;
}

return largestArea;
}

int main()
{
int n;
while (scanf("%d", &n)){
if (n == 0)
return 0;

for (int i = 0; i < n; i++)
{
scanf("%d", &histogram[i]);
}

FindRightSideLowerRec(n);
FindLeftSideLowerRec(n);
long long larea = CalLargestRectangle(n);

printf("%I64d\n", larea);

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: