题目来源:http://poj.org/problem?id=2082
一看题目叙述,确实挺吓人的。其实本题是用集合的形式表示最大矩形的问题。
集合B表示的是一个又一个连续的长度为wi,高为hi的矩形,注意矩形是一个紧邻另一个的。
找最大的矩形,矩形是集合B表示的面积的一部分。
思路与http://blog.csdn.net/moon_sky1999/article/details/77150879中的类似。
数组l表示第i为的矩形向左l[i]位后高度高于第i位的,也就是从第i-1到第i-l[i]+1位的矩形均比第i位的低。
数组llen[i]表示从第i-l[i]+1位到第i位的横轴距离之和。
r[i]、rlen[i]类似。
这样最大矩形的面积即为max((llen[i]+rlen[i]-w[i])*h[i])。
代码:
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
int n;
const int maxn=1e5+10;
int w[maxn];
int h[maxn];
int l[maxn];
int r[maxn];
int llen[maxn];
int rlen[maxn];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n;
while(n!=-1)
{
memset(w,0,sizeof(w));
memset(h,0,sizeof(h));
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
memset(llen,0,sizeof(llen));
memset(rlen,0,sizeof(rlen));
for(int i=1;i<=n;i++)cin>>w[i]>>h[i];
for(int i=1;i<=n;i++)
{
l[i]=1;
llen[i]+=w[i];
int t=i-1;
while(t>=1&&h[i]<=h[t])
{
l[i]+=l[t];
llen[i]+=llen[t];
t-=l[t];
}
}
for(int i=n;i>=1;i--)
{
r[i]=1;
rlen[i]+=w[i];
int t=i+1;
while(t<=n&&h[i]<=h[t])
{
r[i]+=r[t];
rlen[i]+=rlen[t];
t+=r[t];
}
}
int tot=0;
for(int i=1;i<=n;i++)
{
tot=max(tot,h[i]*(llen[i]+rlen[i]-w[i]));
}
cout<<tot<<endl;
cin>>n;
}
return 0;
}