51NOD 1102面积最大的矩形(单调栈)
https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1102
普通写法:dp,预处理出每个点最左边和最右边的距离。
#include<bits/stdc++.h> using namespace std; long long l[50005],r[50005],a[50005]; main() { long long n,k,i; long long ans=0; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; for(i=1;i<=n;i++) { k=i-1; while(a[i]<=a[k]) k=l[k]-1; l[i]=k+1; //printf("l%lld\n",l[i]); } for(i=n;i>=1;i--) { k=i+1; while(a[i]<=a[k]) k=r[k]+1; r[i]=k-1; //printf("r%lld\n",r[i]); } for(i=1;i<=n;i++) { ans=max(ans,a[i]*(r[i]-l[i]+1)); } printf("%lld\n",ans); }
用单调递减栈维护。
#include<cstdio> #include<stack> using namespace std; __int64 f[50010]; int main() { int n,i,ans; __int64 temp,sum=0; stack<int>s; scanf("%d",&n); while(!s.empty()) s.pop(); for(i=0;i<n;i++) scanf("%I64d",&f[i]); f[n]=-1; for(i=0;i<=n;i++) { if(s.empty()||f[i]>f[s.top()]) { s.push(i); } else if(f[i]<f[s.top()]) { while(!s.empty()&&f[i]<f[s.top()]) { temp=(i-s.top())*f[s.top()]; if(temp>sum) sum=temp; ans=s.top(); s.pop(); } s.push(ans); f[ans]=f[i]; } } printf("%I64d\n",sum); return 0; }