POJ2796
题目意思就是给你一个序列,让你求其中一个子序列使得这个子序列和乘以这个子序列中最小值后最大。最初以为要用什么RMQ,还单独去查了下这方面的资料,后来看到了牛人写的这个算法才知道是这么的简单!
总体复杂度超过O(n)但远低于O(n^2)。
#include<stdio.h>
int d[100002];
int s[100002],e[100002];
__int64 sum[100002];
int main()
{
int n;
while(scanf("%d",&n)==1)
{
int i,j,p,q;
__int64 max=-1;
d[0]=-1;
s[0]=1;
sum[0]=0;
d[n+1]=-1;
for(i=1;i<=n;i++)
{
scanf("%d",&d[i]);
j=i-1;
while(j>=0)//d[i]>d[i-1] : s[i]=i d[i]<=d[i-1]:
{
if(d[i]>d[j])
{
s[i]=j+1;
break;
}
else
j=s[j]-1;
}
sum[i]=sum[i-1]+d[i];
}
for(i=n;i>0;i--)
{
j=i+1;
while(j<=n+1)
{
if(d[i]>d[j])
{
e[i]=j-1;
break;
}
else
j=e[j]+1;
}
}
for(i=1;i<=n;i++)
{
if ( (sum[e[i]]-sum[s[i]-1])*d[i]>max)
{
max=(sum[e[i]]-sum[s[i]-1])*d[i];
p=s[i];
q=e[i];
}
}
printf("%I64d\n",max);
printf("%d %d\n",p,q);
}
return 0;
}
浙公网安备 33010602011771号