zoukankan      html  css  js  c++  java
  • V

    两种思路:

    1 单调栈:维护一个单调非递减栈,当栈为空或者当前元素大于等于栈顶元素时就入栈,当前元素小于栈顶元素时就出栈,出栈的同时计算当前值,当前值所包含的区间范围为从当前栈顶元素到当前元素i的距离加上栈顶元素到第二个栈顶元素的距离。

    code:

      

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=1E5+7;
    ll arr[N];
    int main(){
        ll n;
        while(cin>>n,n){
            ll ans=0;
            stack<ll >st;
            for(ll i=1;i<=n;i++) cin>>arr[i];
            arr[n+1]=0;
            for(ll i=1;i<=n+1;i++){
                if(st.empty()||arr[st.top()]<=arr[i]) st.push(i);
                else {
                    ll c=st.top();
                    while(st.size()&&arr[c]>arr[i]){
                        st.pop();
                        if(st.empty()) ans=max(ans,arr[c]*(i-1));
                        else {
                            ans=max(ans,(i-st.top()-1)*arr[c]);
                            c=st.top();
                        }
                    }
                    st.push(i);
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }

    2 dp

      维护两个数组left和right,left[i]表示元素i向大于当前元素向左的最大连续延伸。right[i]同理。

         转移方式:j=left[j]-1,j=right[j]+1。然后遍历每个元素ans=max(ans,(right[i]-left[i]+1)*arr[i]) 

      code:

      

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=1E5+7;
    ll arr[N];
    ll left1[N];
    ll right1[N];
    int  main(){
        ll n;
        while(scanf("%lld",&n)!=EOF&&n){
            for(ll i=1;i<=n;i++){
                scanf("%lld",&arr[i]);
                left1[i]=right1[i]=i;
            }
            for(ll i=1;i<=n;i++){
                ll j=i;
                while(j>=1&&arr[i]<=arr[j]) j=left1[j]-1;
                left1[i]=j+1;
            }
            for (ll i=n-1; i>=1; i--) {
                ll j=i;
                while (j<=n && arr[i]<=arr[j])  j=right1[j]+1;
                right1[i]=j-1;
            }
            ll ans=0;
            for(ll i=1;i<=n;i++){
                ans=max(ans,(right1[i]-left1[i]+1)*arr[i]);
            }printf("%lld
    ",ans);
        }
        return 0;
    }

             

  • 相关阅读:
    从1.5k到18k, 一个程序员的5年成长之路
    我是如何准备技术面试的
    10个惊艳的Ruby单行代码
    经典Spring面试题和答案
    数据分析应该要避免的6个错误
    代码重构的实战经验和那些坑
    勾勒物联网与大数据的数据中心路线图
    共筑Spark大数据引擎的七大工具
    es6学习总结(一)
    vue-cli搭建与vue-router(路由配置)
  • 原文地址:https://www.cnblogs.com/Accepting/p/12546597.html
Copyright © 2011-2022 走看看