题目链接:[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;
}