DP激情奉献(三)hdu1506状图选最大矩形

来源:互联网 发布:fc2最新域名设置 编辑:程序博客网 时间:2024/05/20 23:31
//题目大意:给一个N,接下来N个数字..形成一个N格大的柱状图..answer问最大的矩形是什么
//最开始想的是优化了直接的N^2的处理方法,对于每个a[i],分别找他的左右两边分别有多少个
//比他要大的..只要遇见小的就break,优化在这儿..但是过不了.
//2次优化.思路还是去求每个a[i]能够带来的矩形宽是多少..
//那么,在这里..比如考虑a[i]的宽的时候..不必从i-1挨个看着走..
//a[i]与a[i-1]比较了以后,就可以直接去找a[i-1]比较失败的那个元素了..
//这样一优化之后,去掉了中间的蛮多不需要的步骤..就不会TLE了.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<math.h>
#include<vector>
#include<algorithm>
using namespace std;
__int64 a[111111];
int r[111111],l[111111];
int main()
{
    int n;
    while(scanf("%d",&n) && n != 0)
    {
        for(int i = 1 ; i <= n ; i++)
        {
            scanf("%I64d",&a[i]);
            r[i] = i;
            l[i] = i;
        }
        __int64 ans = 0;
        a[0] = -1;a[n+1] = -1;
        for(int i = 1 ; i <= n ; i++)
        {
            while(a[l[i]-1] >= a[i])
            {
                l[i] = l[l[i]-1];
            }
        }
        for(int i = n ; i >= 1 ; i--)
        {
            while(a[r[i]+1] >= a[i])
            {
                r[i] = r[r[i]+1];
            }
        }
        __int64 sum;
        for(int i = 1 ; i <= n ; i++)
        {
            //printf("%d  %d  %d\n",i,l[i],r[i]);
            sum = a[i] * (r[i] - l[i] + 1);
            ans = max(sum,ans);
        }
        printf("%I64d\n",ans);
    }
}