题目大意:给你许多组数据,每组数据都给一个n与n个数字
每段区间的值=(这段区间的最小值*这段区间所有数的和)
问你每组数据区间最大的值是多少
(具体请参照题目)
思路:
主要思路不难,就是找一个数a[i]然后向左右两边延申并要保持a[i]一直是最小值的最大区间
然后前缀和求区间和并计算答案即可
难的主要还是代码实现(具体看代码)
参考了别人的代码
AC代码:
#include <iostream> #include <cstdio> using namespace std; long long a[100010]; long long sum[100010]; int l[100010]; int r[100010]; int main() { int t; int ccase=0; while(scanf("%d",&t)!=EOF){//注意题目是给多组数据,要用EOF sum[0]=0; for(int i=1;i<=t;i++){ cin>>a[i]; sum[i]=sum[i-1]+a[i];//前缀和 l[i]=i;//预处理,求最小值区间 r[i]=i; } a[0]=-1; a[t+1]=-1; for(int i=1;i<=t;i++){//求最小值的左边的区间延申 while(a[i]<=a[l[i]-1]){ l[i]=l[l[i]-1];//如果当前数是最小值则再向左边延申 } } for(int i=t;i>=1;i--){//求最小值右边的区间延申 while(a[i]<=a[r[i]+1]){ r[i]=r[r[i]+1]; } } int L=1,R=1;//记录边界 long long ans=0; for(int i=1;i<=t;i++){ long long cnt=sum[r[i]]-sum[l[i]-1];//区间和 if(cnt*a[i]>ans){ ans=cnt*a[i]; L=l[i];//记录边界 R=r[i]; } } if(ccase++)cout<<endl; cout<<ans<<endl; cout<<L<<' '<<R<<endl; } return 0; }