• 单调栈


    单调栈

    水几道单调栈。。。

    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
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    091122杂记
    20100304我的碎碎念
    写给自己
    开始学习AGG
    找两个数组中的相同元素
    要多写代码了
    [翻译] AGG Reference 之 Basic Renderers(基础渲染器)
    在博客园日志中显示数学公式(旧,ASCIIMathML.js版说明)
    091128日志(博客园博客显示数学公式的方法!)
    与临时对象的斗争(上)
  • 原文地址:https://www.cnblogs.com/--560/p/4741843.html
Copyright © 2020-2023  润新知