首页 > 代码库 > 单调栈
单调栈
Largest Rectangle in a Histogram
POJ - 2559
用结构体存矩形的宽和高。
如果新来的矩形高小于等于栈顶的矩形,就弹出,并计算更新面积,把栈顶的矩形宽度累加到下一个矩形。
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 #define ll long long 5 const int maxn=100010; 6 ll top; 7 ll ans; 8 struct Node{ 9 ll h,w; 10 }node; 11 Node s[maxn]; 12 int main(){ 13 ll n; 14 while(scanf("%lld",&n)&&n){ 15 ans=0; 16 top=0; 17 for(int i=0;i<n;i++){ 18 ll x; 19 scanf("%lld",&x); 20 node.h=x; 21 node.w=1; 22 ll w=0; 23 while(top&&s[top].h>=x){ 24 Node a=s[top--]; 25 ll temp=a.h*(a.w+w); 26 w+=a.w; 27 if(temp>ans) ans=temp; 28 } 29 node.w+=w; 30 s[++top]=node; 31 } 32 ll w=0; 33 while(top){ 34 Node a=s[top--]; 35 ll temp=a.h*1LL*(a.w+w); 36 w+=a.w; 37 if(ans<temp) ans=temp; 38 } 39 printf("%lld\n",ans); 40 } 41 }
Bad Hair Day
POJ - 3250
考虑当前牛能被多少牛看见,维护一个单调递减栈。
1 #include<cstdio> 2 const int N=80000; 3 int n,x,s[N],top; 4 long long ans; 5 int main() 6 { 7 scanf("%d",&n); 8 for(int i=1;i<=n;i++) 9 { 10 scanf("%d",&x); 11 while(top&&s[top]<=x)top--; 12 ans+=top;//栈底从1开始,这样top就是元素,很方便 13 s[++top]=x; 14 } 15 printf("%lld",ans); 16 return 0; 17 }
Feel Good
POJ - 2796
先从两边各扫一遍找到每一个元素的左边界和右边界,使得它在这个区间内最小。
然后扫一遍更新最大值即可。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 const int maxn=100010; 6 int a[maxn],L[maxn],R[maxn]; 7 long long s[maxn]; 8 9 int main(){ 10 int n; 11 scanf("%d",&n); 12 for(int i=1;i<=n;i++){ 13 scanf("%d",&a[i]); 14 L[i]=R[i]=i; 15 s[i]=s[i-1]+a[i]; 16 } 17 a[0]=a[n+1]=-1; 18 for(int i=1;i<=n;i++){ 19 while(a[i]<=a[L[i]-1]) L[i]=L[L[i]-1]; 20 } 21 for(int i=n;i>0;i--){ 22 while(a[i]<=a[R[i]+1]) R[i]=R[R[i]+1]; 23 } 24 long long ans=-1; 25 int l,r; 26 for(int i=1;i<=n;i++){ 27 long long temp=(s[R[i]]-s[L[i]-1])*1ll*a[i]; 28 if(ans<temp){ 29 ans=temp; 30 l=L[i]; 31 r=R[i]; 32 } 33 } 34 printf("%lld\n%d %d\n",ans,l,r); 35 }
单调栈
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。