[XJOI]3606 最大子矩形的面积

题目大意:有一系列的长条状的矩形,宽度都为1,相邻的竖立在x轴上,都有一个高度h[i],求最大的子矩形面积。要求该矩形全部都在长条状的矩形上。

首先能否证明,最大子矩形的高度一定与某一个长条状矩形相等。这其实很好证明,可以利用反证法和一点点增广的思想——如果没有与任何一个长条状矩形的高度相等,意味着我完全可以让它再高一点点,并且是没有问题的,因为如果不能再往上了,必定有一个地方的高度已经与长条状举行的高度相等了。

既然已经确定了该子矩形的高度与某一个长条状矩形相等了,那么我们就可以一个个矩形枚举过去,以该矩形为基准矩形的高度往两边扩展,找到其能够到达的最远的左右边界来算出面积打擂。而扩展的条件也很简单,要求两边的长条状矩形的高度连续且>=基准矩形的高度。这样的复杂度是O(n ^ 2)

我们想办法来优化一下往两边扩展的过程——不要让以前做过的东西白做,要利用一点历史结果。于是我们想到了dp。令left[i]表示矩形i所能到达的最左的左边界,right[i]类似。初始化:left[1]=1,right[n]=n;

我们考虑对于left[i]怎么求,right[i]类似。对于left[i],首先初始化left[i]=i(它本身)。既然left[i-1]到以前的都已经求好了。那么我们只需要判断对于矩形i,如果矩形i-1的高度要>=矩形i,也就是它左边的矩形大于等于它,那么就可以用它左边的那个矩形的最远左边界来更新它,因为left[i-1]已经求好了,并且这一段区间内的矩形高度都>=矩形i-1,自然>=矩形i。那么也就是就可以用left[left[i]-1]来更新left[i],接下来,再利用下一个的左边界,如果依然满足>=矩形i,那么继续迭代……直到1为止。

Code

/*By QiXingzhi*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define  r  read()
#define  Max(a,b)  (((a)>(b)) ? (a) : (b))
#define  Min(a,b)  (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
#define int ll
const int N = 100010;
const int INF = 715827882;
inline int read(){
    int x = 0; int w = 1; register int c = getchar();
    while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
    if(c == '-') w = -1, c = getchar();
    while(c >= '0' && c <= '9') x = (x << 3) +(x << 1) + c - '0', c = getchar();
    return x * w;
}
int n,m,ans;
int a[N],left[N],right[N];
#undef int
int main(){
#define int ll
    n = r;
    for(int i = 1; i <= n; ++i){
        a[i] = r;
    }
    left[1] = 1;
    for(int i = 2; i <= n; ++i){
        left[i] = i;
        while(left[i] >= 1 && a[left[i]-1] >= a[i]){
            left[i] = left[left[i]-1];
        }
    }
    right[n] = n;
    for(int i = n-1; i >= 1; --i){
        right[i] = i;
        while(right[i] <= n && a[right[i]+1] >= a[i]){
            right[i] = right[right[i]+1];
        }
    }
    for(int i = 1; i <= n; ++i){
        ans = Max(ans, a[i] * (right[i] - left[i] + 1));
    }
    printf("%lld",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qixingzhi/p/9278467.html
今日推荐