最大矩形

最大矩形-HDU1506

题目链接:[Problem - 1506 (hdu.edu.cn)]

1.高度序列在相同时,最大的矩形很好算:

最大矩形

i=1 s=h*1

i=2 s=h*1+h*1

i=3 s=h*1+h*1+h*1

... ...
也就是s=高度*数组长度

2.高度不同,但是单调增时:

最大矩形

算了第五列一列的面积之后,由于第四列可以“延伸”到第五列所以第四列的宽度要更新为2。

同理第三列宽度为3,第二列宽度为4,第一列宽度为5。

根据这个性质,可以维护一个栈顶到栈底递减的单调栈。

3.以以下数据作为例子:

最大矩形

1=> 4入栈,对应宽度置1

2=> 2入栈会破坏栈递减的单调性,4出栈并且更新“ans”为4,2入栈宽度更新为2

3=> 3入栈

4=> 2入栈会破坏栈递减单调性,之前的2,3出栈,这个2宽度更新为4

5=> 5入栈

至此,我们得到的图就变成了这样:(高度为2长度为4和高度为5,长度为1)

最大矩形

最后我们只要将0压入队列,就能更新出需要的答案。
因为0是高度中最小的,将0压栈等于把栈内全部元素弹栈,在弹栈的过程中就更新了ans值。

总结

整个过程很像是在将数列中“高挑”的数字减少到和周围齐平。意会一下8。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int N = 1e6+10;
typedef long long ll; 
using namespace std;
int n;
int a[N],w[N],stk[N];

void solve(){
	int p=0;
	ll ans=0;
	rep(i,1,n+1){
		int width = 0;
		while(p && a[i]<=stk[p]){
			width+=w[p];
			ans=max(ans,(ll)stk[p--]*width);
            //要注意ans是ll,要用(ll)强制转换
		}
		stk[++p]=a[i];
		w[p]=width+1;//延申到前面的宽度要加上自己的宽度 
	}
	printf("%lld\n",ans);
}

int main(){
	while(scanf("%d",&n)){
		if(!n)return 0;
		memset(a,0,sizeof a);
		memset(w,0,sizeof w);
		memset(stk,0,sizeof stk);
		rep(i,1,n)scanf("%d",&a[i]);
		solve();
	}
}

最大矩形

上一篇:QML ChartView 学习


下一篇:请求不同端口的接口