zoukankan      html  css  js  c++  java
  • 单调栈

    描述:求一个数组的某一个数,向左右两边延申的最大区间,比如1276453.对于4可以向左延申到7,向右延申到5,也就是4在这个区间内是最小值。

    适用:对于一个数组,如果对于全部区间去求解,需要n*(n-1)/2个区间,所以问题的复杂度至少是N的平方,如果换一个角度,所有的区间都是以某一个数字作为最小值的,所以只要求出一个数代表一个区间,就可以转换为O(n)的复杂度。

    #include<stdio.h>
    #include<math.h>
    #include<iostream>
    #include<stack>
    using namespace std;
    const int maxn=100010;
    long long a[100010];
    int l[100010],r[100010],n,ansl,ansr,top;
    
    long long  sum[100010]={0},ans=-1;
    
    int main(){
    int i,j;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
    scanf("%lld",&a[i]);
    sum[i]=sum[i-1]+a[i];
    l[i]=r[i]=i;
    } 
    a[0]=a[n+1]=-1;
    
    stack<int>s;   
    for(i=1;i<=n+1;i++){
    while(!s.empty()&&a[i]<=a[s.top()]  ){//a[i]<栈顶,出栈 
     r[s.top()] =i-1;//找出栈顶元素的下标右端点 
     s.pop();
    }  
    if(!s.empty())l[i]=s.top()+1;  
    else l[i]=1;
       s.push(i);
    
    } 
    
    long long tmp;
    for(i=1;i<=n;i++){
    
    tmp=(sum[r[i]]-sum[l[i]-1])*a[i];
    if(tmp>=ans){
    ans=tmp;
    ansl=l[i];
    ansr=r[i];
    } 
    }
    printf("%lld
    ", ans);
      printf("%d %d
    ", ansl, ansr);
    return 0;
    }
  • 相关阅读:
    用GitHub Pages搭建博客(三)
    Beta阶段项目总结
    最终团队绩效评估
    Alpha阶段项目总结
    项目发布
    Alpha版总结会议
    第二次冲刺周期站立会议(10)
    第二次冲刺周期站立会议(9)
    第二次冲刺周期站立会议(8)
    第二次冲刺周期站立会议(7)
  • 原文地址:https://www.cnblogs.com/mdumpling/p/9501271.html
Copyright © 2011-2022 走看看