[HDU1506]Largest Rectangle in a Histogram[dp]

题目链接:[HDU1506]Largest Rectangle in a Histogram[dp]

题意分析:给出多个矩形条,高度随机(0 <= h <= 1000000000)。同一水平并排在一起,在它们围成的图形上,划出一块矩形,使得这块矩形的面积最大~

解题思路:对于每一块木板,我们可以将他向左右扩散,扩散规则为:左右大于我,我就往那边走。l[i], r[i]分别用于记录第i个板能扩散到的最左边和最右边,

于是有:面积 = h[i] * (r[i] - l[i] + 1); O(n)遍历面积求出最大值

个人感受:最初的时候想得是来个dp[i]代表到第i个最大的面积,发现转移还要判断好多东西,结果这种解法给很好解决了orz。另外在确定l[i]和r[i]时,遍历条件的左右极值约束没加,TLE了N发!!!不开桑TAT Debug了半天。

具体代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 100110;
typedef long long ll;

ll l[MAXN], r[MAXN], h[MAXN];

int main() {
    int n;
    while (scanf("%d", &n) && n)
    {
        for (int i = 1; i <= n; ++i)
        {
            scanf("%lld",&h[i]);
            l[i] = r[i] = i;
        }
        for (int i = 1; i <= n; ++i)
        {
            while (l[i] >= 2 && h[l[i] - 1] >= h[i]) //i板能到达的最左边
                l[i] = l[l[i] - 1];
        }
        ll ans = 0, tem = 0;
        for (int i = n; i >= 1; --i)//注意循环方向
        {
            while (r[i] <= n - 1 && h[r[i] + 1] >= h[i]) //i板能到达的最右边
                r[i] = r[r[i] + 1];
            tem = h[i] * (r[i] - l[i] + 1); //查找最大值
            if (ans < tem)
                ans = tem;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

你可能感兴趣的:(dp,HDU)