SP1805 HISTOGRA (单调栈)

单调栈维护栈顶为高度最大的

记下来栈中每个元素入栈时顶掉的最靠左的一个位置(如果没顶掉就是它本身),那么在它出栈的时候,它所带来的面积就是(出栈位置-记录位置)*高度 (可能会有加一减一之类的细节)

 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 }
原文地址:https://www.cnblogs.com/Ressed/p/9833544.html