题意:给你一些板子,板子的长是1,有一个高度ai,不能打乱顺序,求出最大的矩形面积
思路:(说实话,不会做)这是挑战程序设计竞赛上的一道题,之前单调栈一直不怎么会,而且最近训练总考单调栈,结果就是排名直线下滑(保佑 啊,不排名不能再++了,还是--吧),单调栈就是维护栈内的元素,只站内的元素是单调的,如果不满足某种程度上的单调就进行弹栈操作,直至符合单调,说实话用的地方挺多的,这道题我是按照白书上的作法做的(再写的时候,有个地方--,写成了++,一直循环报错,尬),白书上的作法就是用单调栈的性质,维护以a[i]为高度的左右的模板编号,而左右时分成两部分进行维护的,L的维护时候从左向右。如果遇到比a[i]小的元素就停止弹栈,因为这时模板a[i]已经不能再向左侧进行扩展了,而右侧的维护与左侧的维护相似,由于单调栈的特性,所以只能从右向左进行维护,遇到小的就不能进行弹栈操作,大概就是这样(雾~);
代码:(爆了发int)
#include <cstdio> #include <algorithm> using namespace std; const int maxn=1e5+7; int n,a[maxn],L[maxn],R[maxn],stk[maxn],top; int main() { while(~scanf("%d",&n)&&n){ a[0]=0;stk[0]=0; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } top=0; for(int i=1;i<=n;i++){ while(a[i]<=a[stk[top]]&&top>0)top--; if(top==0){ L[i]=0; } else L[i]=stk[top]; stk[++top]=i; } // printf("test "); top=0; for(int i=n;i>=1;i--){ // printf("test %d ",i); while(a[i]<=a[stk[top]]&&top>0)top--; if(top==0){ R[i]=n; } else R[i]=stk[top]-1; stk[++top]=i; } long long maxx=-1; for(int i=1;i<=n;i++){ maxx=max(maxx,(long long)(R[i]-L[i])*a[i]); } printf("%lld ",maxx); } return 0; }