单调栈

单调栈

水几道单调栈。。。

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;
}
View Code

 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;
}
View Code

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;
}
View Code

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;
}
View Code

 

posted @ 2015-08-19 12:10  __560  阅读(218)  评论(0编辑  收藏  举报