单调栈维护栈顶为高度最大的
记下来栈中每个元素入栈时顶掉的最靠左的一个位置(如果没顶掉就是它本身),那么在它出栈的时候,它所带来的面积就是(出栈位置-记录位置)*高度 (可能会有加一减一之类的细节)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define LL long long int 5 using namespace std; 6 const int maxn=100010; 7 8 int rd(){ 9 int x=0,neg=1;char c=getchar(); 10 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*neg; 13 } 14 15 //题意:给一些并排放置的宽度相等的矩形,要求在其中截一个矩形出来,求截出的最大的面积 16 //从前往后做,每次加入一个长度,同时记录它进来的时间 17 //若栈中有比它长度大的,将它们出栈,并将当前记录的时间改为已出栈的的最早时间,同时更新答案为(当前时间-出栈的的记录时间)*出栈的的长度 18 //最后可以假装有一个长度为0的来使所有人出栈,方便统计答案 19 20 int N; 21 int s[maxn][2],head; 22 LL ans; 23 24 int main(){ 25 int i,j,k; 26 while(1){ 27 N=rd();if(!N) break; 28 ans=0; 29 head=1;s[1][0]=rd();s[1][1]=1; 30 for(int t=2;t<=N+1;t++){ 31 if(t<=N) j=rd();else j=0; 32 for(i=head,k=t;i;i--){ 33 if(s[i][0]>=j) k=min(k,s[i][1]),ans=max(ans,1ll*s[i][0]*(t-s[i][1])); 34 else{ 35 head=i+1;s[head][0]=j;s[head][1]=k;break; 36 } 37 }if(!i){head=1;s[1][0]=j;s[1][1]=k;} 38 } 39 printf("%lld ",ans); 40 } 41 }