• POJ 2796 Feel Good(单调栈)


    题目链接:Feel Good

    题意:给定长度为n的数字序列ai,定义某值为区间[l,r]内ai之和乘上区间[l,r]内最小的ai。求最大的该值。

    题解:单调栈维护每个ai前面和后面第一个比它小的位置,对应题目中要求的值就为该区间之和乘上ai,从头往后遍历一遍。

    数组:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 typedef long long ll;
     8 const int N=2e5+10;
     9 ll a[N],sum[N];
    10 int l[N],r[N],st[N];
    11 
    12 int main(){
    13     int n;
    14     scanf("%d",&n);
    15     for(int i=1;i<=n;i++){
    16         scanf("%lld",&a[i]);
    17         sum[i]=sum[i-1]+a[i];
    18     }
    19     int top=0;
    20     for(int i=1;i<=n;i++){
    21         while(top>0&&a[i]<=a[st[top]]) top--;
    22         l[i]=top==0?1:st[top]+1;
    23         st[++top]=i;
    24     }
    25     top=0;
    26     for(int i=n;i>=1;i--){
    27         while(top>0&&a[i]<=a[st[top]]) top--;
    28         r[i]=top==0?n:st[top]-1;
    29         st[++top]=i;
    30     }
    31     ll ans=-1;
    32     int id=0;
    33     for(int i=1;i<=n;i++){
    34         ll res=(sum[r[i]]-sum[l[i]-1])*a[i];
    35         if(res>ans) ans=res,id=i;
    36     }
    37     printf("%lld
    ",ans);
    38     printf("%d %d
    ",l[id],r[id]);
    39     return 0;
    40 }
    View Code

    stack:

     1 #include <stack>
     2 #include <cstdio>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 typedef long long ll;
     8 const int N=1e5+10;
     9 
    10 stack <int> st;
    11 int l[N],r[N],id;
    12 ll a[N],sum[N],ans=-1;
    13 
    14 int main(){
    15     int n;
    16     scanf("%d",&n);
    17     for(int i=1;i<=n;i++){
    18         scanf("%lld",&a[i]);
    19         sum[i]=sum[i-1]+a[i];
    20     }
    21     for(int i=1;i<=n;i++){
    22         while(st.size()&&a[st.top()]>=a[i]) st.pop();
    23         l[i]=(st.size()==0)?1:st.top()+1;
    24         st.push(i);
    25     }
    26     while(st.size()) st.pop();
    27     for(int i=n;i>=1;i--){
    28         while(st.size()&&a[st.top()]>=a[i]) st.pop();
    29         r[i]=(st.size()==0)?n:st.top()-1;
    30         st.push(i);
    31     }
    32     for(int i=1;i<=n;i++){
    33         ll res=(sum[r[i]]-sum[l[i]-1])*a[i];
    34         if(res>ans) ans=res,id=i;
    35     }
    36     printf("%lld
    ",ans);
    37     printf("%d %d
    ",l[id],r[id]);
    38     return 0;
    39 }
    View Code
  • 相关阅读:
    方法参数的传递方式
    方法设计
    接口
    SQL 安装MySQL
    Windows 10 安装 wordpress
    Windows10安装PHP7+Apache 2.4
    做一个增删改查的工程
    清除缓存
    创建POJO
    VI快捷键
  • 原文地址:https://www.cnblogs.com/pavtlly/p/10002161.html
Copyright © 2020-2023  润新知