http://acm.hdu.edu.cn/showproblem.php?pid=1506
一道写了很久的题,以前看过,都没什么感觉,今天终于把它搞懂了。很多人都说是DP,但我没感觉出来,好像就是YY题了。
题目中叫求一个最大的区域,则第i个矩形对应的面积是ave[i] = (r[i] - l[i] + 1) * a[i];l[i]表示以它这个高度所能到达的最左边的位置(最左一个高度不小于它的高度的位置),而r[i]表示能到达的最右边的位置(最右一个高度不小于它的高度的位置)。
那么这个题目就转到怎么求r[]和l[]上了。如果每次依次向左向右找,肯定会超时的。这时就会用到迭代了,比如说求a[i]的l[i],如果a[i]大于a[i-1]那么l[i] = i,这个不难理解,不解释;如果a[i]小于a[i-1],那么l[i]肯定小于l[i-1],找l[i]就可以直接跳到l[i-1]的位置上,在往左去找了。
__int64 a[100005];
int r[100005];
int l[100005];
int main()
{
int n,i,k;
while(scanf("%d",&n)!=EOF && n!=0)
{
scanf("%d",&a[1]);
l[0] = 0;
l[1] = 1;
for(i=2;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i] > a[i-1])
l[i] = i;
else
{
k = i;
while(k--)
{
if(a[k] < a[i])
{
l[i] = k+1;
break;
}
else
{
k = l[k];
}
}
}
}
r[n] = n;
for(i=n-1;i>=1;i--)
{
if(a[i] > a[i+1])
r[i] = i;
else
{
k = i;
while((++k) != n+1)
{
if(a[k] < a[i])
{
r[i] = k-1;
break;
}
else
{
k = r[k];
}
}
if(k == n+1)
r[i] = n;
}
}
__int64 max = 0;
for(i=1;i<=n;i++)
{
__int64 ave = (r[i] - l[i] + 1) * a[i];
if(ave > max)
max = ave;
}
printf("%I64d/n",max);
}
return 0;
}