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
原文地址:https://www.cnblogs.com/pavtlly/p/10002161.html