(寒假马拉松第一场 G题)
题意:
本题主要就是要求一个数列里面,连续的几个数的和乘以这个连续段里最小的一个数,在所有这样连续数列里最大的一个
分析:
我是简单模拟着做的,直接输出最大值就可以了。
网上很多都说,用单调栈 / 单调队列,要去学习学习!
| 2796 | Accepted | 2612K | 797MS | G++ | 849B | 2014-02-10 17:07:51 |
#include<iostream> #include<cstdio> #include<cstring> #define LL long long using namespace std; const int N=100005; int begin[N],end[N],num[N]; LL sum[N]; int main(){ int i,n,b,e; LL ans=-1,t; memset(sum,0,sizeof sum); scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%d",&num[i]); sum[i]=sum[i-1]+num[i]; begin[i]=i; end[i]=i; } //for(i=1;i<=n;i++) printf("%d ",num[i]); //puts(""); //for(i=1;i<=n;i++) printf("%d ",sum[i]); //puts(""); for(i=2;i<=n;i++) while(begin[i]>1 && num[begin[i]-1]>=num[i]) begin[i]=begin[begin[i]-1]; for(i=n-1;i>0;i--) while(end[i]<n && num[end[i]+1]>=num[i]) end[i]=end[end[i]+1]; for(i=1;i<=n;i++){ t=(sum[end[i]]-sum[begin[i]-1])*num[i]; if(t>ans){ ans=(LL)t; b=begin[i]; e=end[i]; } } printf("%lld\n%d %d\n",ans,b,e); return 0; }
本文解析了一道关于寻找数列中连续子序列最优值的问题。通过模拟算法确定每个元素为最小值时对应的子序列范围,并计算该子序列的和与最小值的乘积,最终输出最大值及其对应的子序列范围。
1132

被折叠的 条评论
为什么被折叠?



