poj2559 (单调栈)
最容易想到的办法是暴力枚举,但是每次计算需要在统计上花费很多时间,单调栈的优势就体现出来了,用单调栈维护一些有用的信息,帮助快速计算矩形面积
单调栈,保证每个矩形高度依次递增,维护一个拓展宽度。由单调栈的性质,栈内元素都不能向之前的元素延伸。当1,2,3依次入栈,单调,所以维护前拓宽度w=1。当访问到4,比栈顶元素高度低,所以3不可能再往后拓展了,那么计算出面积尝试跟新最大值,3出栈,维护栈顶的2的总长度为w(2)+= w(3);即2向后延拓的长度,直到遇到一个比4低的栈顶元素,把4加入栈,4的前拓宽度最后一个出栈的元素加1。
重复上述过程直到访问完所有矩形,此时如果栈没空把栈中元素依次退出并计算面积。
今天模拟软考时遇到这个问题了,虽然知道要用单调栈,然而并不清楚具体用法。果然还是too young too naive。
#include<bits/stdc++.h> using namespace std; struct node{ int w,h; }S[1100];; int main() { //freopen("in.txt","r",stdin); int tp = 0; S[tp].w = 0; S[tp].h = 0; int n; scanf("%d",&n); int ans = 0; while(n--){ int t; scanf("%d",&t); if(t>S[tp].h){ S[++tp].h = t; S[tp].w = 1; } else { int cnt = 0; do{ ans = max(ans,S[tp].h*S[tp].w); S[tp-1].w += S[tp].w; tp--; }while(S[tp].h >= t); S[tp].w -= S[tp+1].w; S[++tp].h = t; S[tp].w +=1; } } if(tp){ do{ ans = max(ans,S[tp].h*S[tp].w); S[tp-1].w += S[tp].w; tp--; }while(tp); } printf("%d",ans); return 0; }