单调栈
水几道单调栈。。。
poj3250:
http://poj.org/problem?id=3250
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<stack> #define REP(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=1000100; typedef long long ll; int N; ll h; stack<ll> s; int main() { while(cin>>N){ while(!s.empty()) s.pop(); ll ans=0; REP(i,1,N){ scanf("%lld",&h); while(!s.empty()&&s.top()<=h) s.pop(); ans+=s.size(); s.push(h); } cout<<ans<<endl; } return 0; }
poj2082:
http://poj.org/problem?id=2082
求最大连续矩形面积。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<stack> #define REP(i,a,b) for(int i=a;i<=b;i++) #define rep(i,a,b) for(int i=a;i>=b;i--) using namespace std; const int maxn=500100; const int INF=(1<<29); typedef long long ll; int n; struct Rec { ll w,h; }; Rec rec; stack<Rec> s; int main() { freopen("in.txt","r",stdin); while(cin>>n&&n!=-1){ while(!s.empty()) s.pop(); ll ans=0; REP(i,1,n){ scanf("%lld%lld",&rec.w,&rec.h); ll tw=0; while(!s.empty()&&s.top().h>=rec.h){ ll tS=(tw+s.top().w)*s.top().h; ans=max(tS,ans); tw+=s.top().w; s.pop(); } rec.w+=tw; s.push(rec); } ll tw=0; while(!s.empty()){ ll tS=(tw+s.top().w)*s.top().h; ans=max(tS,ans); tw+=s.top().w; s.pop(); } cout<<ans<<endl; } return 0; }
poj2559:同上。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<stack> #define REP(i,a,b) for(int i=a;i<=b;i++) #define rep(i,a,b) for(int i=a;i>=b;i--) using namespace std; const int maxn=500100; const int INF=(1<<29); typedef long long ll; int n; struct Rec { ll w,h; }; Rec rec; stack<Rec> s; int main() { //freopen("in.txt","r",stdin); while(cin>>n&&n){ while(!s.empty()) s.pop(); ll ans=0; REP(i,1,n){ rec.w=1; scanf("%lld",&rec.h); ll tw=0; while(!s.empty()&&s.top().h>=rec.h){ ll tS=(tw+s.top().w)*s.top().h; ans=max(tS,ans); tw+=s.top().w; s.pop(); } rec.w+=tw; s.push(rec); } ll tw=0; while(!s.empty()){ ll tS=(tw+s.top().w)*s.top().h; ans=max(tS,ans); tw+=s.top().w; s.pop(); } cout<<ans<<endl; } return 0; }
xdoj1100:
http://acm.xidian.edu.cn/problem.php?id=1100
求区间最小值乘以区间长度的最大值。转化为最大连续矩形面积。。
#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define rep(i,a,b) for(int i=a;i>=b;i--) using namespace std; const int maxn=1000100; typedef long long ll; int n; ll a[maxn],w[maxn]; ll h[maxn]; struct node { ll w,h; }; stack<node> s; int main() { while(cin>>n){ while(!s.empty()) s.pop(); REP(i,1,n) scanf("%lld",&a[i]); n--; REP(i,1,n) scanf("%lld",&w[i]),h[i]=min(a[i],a[i+1]); ll ans=0; REP(i,1,n){ ll tw=0; while(!s.empty()&&s.top().h>=h[i]){ ll tS=(tw+s.top().w)*s.top().h; ans=max(tS,ans); tw+=s.top().w; s.pop(); } s.push({tw+w[i],h[i]}); } ll tw=0; while(!s.empty()){ ll tS=(tw+s.top().w)*s.top().h; ans=max(tS,ans); tw+=s.top().w; s.pop(); } cout<<ans<<endl; } return 0; }