POJ-2559Largest Rectangle in a Histogram(单调栈)
题目链接:http://poj.org/problem?id=2559
题目大意:给你n个长方形,每个长方形的高为$h_i$,底为1,问最大的矩形面积可以是多少
Sample Input
7 2 1 4 5 1 3 3 4 1000 1000 1000 1000 0
Sample Output
8 4000
emmmm,暴力计算的话就是看看两边能够最多延伸到哪里,那么我们可以用单调栈来维护一个递增的矩形,那么它就不需要再检查左边的,在添加新元素的时候,如果比栈顶元素大,直接往里面扔,否则的话我们就需要一点操作了。
想想我们单调栈维护的是每个元素向左边能够延伸的最小的坐标,也就是最大长度,那么当剔除掉栈顶的时候,我们就需要对栈顶直接进行计算:$ans=max(ans,1LL*(i-stk[tail])*h[stk[tail]])$,我相信这个很好理解,$i$是向右延伸的最大坐标+1,$stk[tail]$是向左延伸的最小坐标。最后,剔除完成之后,我们知道,第$i$个位置也可以延伸到这里,那么也就是说$stk[++tail]=stk[tail]$,同时我们将这个位置的高度也进行变化:$h[stk[tail]]=h[i]$。。。那么代码也就基本出来了。
以下是A
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int mac=1e5+10; ll h[mac]; int stk[mac]; int main() { int n; while (scanf ("%d",&n)){ if (!n) return 0; for (int i=1; i<=n; i++) scanf ("%lld",&h[i]); int head=1,tail=0; ll ans=0; h[n+1]=-1; for (int i=1; i<=n+1; i++){ if (head>tail || h[stk[tail]]<=h[i]) {stk[++tail]=i; continue;} while (head<=tail && h[stk[tail]]>h[i]){ ans=max(ans,1LL*(i-stk[tail])*h[stk[tail]]); tail--; } stk[++tail]=stk[tail]; h[stk[tail]]=h[i]; } printf("%lld\n",ans); } return 0; }
C代码:
路漫漫兮