题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1506
思路
就只需要找到当前每一个矩形,以它的高度,向左向右分别能延伸多长即可
直接暴力肯定会T,其实每次能延伸的都和上一次有关系,因此考虑dp
状态表示
l[i]:以当前矩形的高度向左能延伸多少
转移
如果h[i] ≥ h[i - 1],那么l[i] = 1,但是在i - 1 - l[i - 1]之前,还存在高度在h[i - 1]和h[i]之间的,还需要累加上
代码
#include <iostream>
#include <cstring>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <climits>
#include <deque>
#include <bitset>
#include <algorithm>
using namespace std;
#define PI acos(-1.0)
#define LL long long
#define PII pair<int, int>
#define PLL pair<LL, LL>
#define mp make_pair
#define IN freopen("in.txt", "r", stdin)
#define OUT freopen("out.txt", "wb", stdout)
#define scan(x) scanf("%d", &x)
#define scan2(x, y) scanf("%d%d", &x, &y)
#define scan3(x, y, z) scanf("%d%d%d", &x, &y, &z)
#define sqr(x) (x) * (x)
#define pr(x) cout << #x << " = " << x << endl
#define lc o << 1
#define rc o << 1 | 1
#define pl() cout << endl
#define CLR(a, x) memset(a, x, sizeof(a))
#define FILL(a, n, x) for (int i = 0; i < n; i++) a[i] = x
const int maxn = 100000 + 5;
const int INF = 0x3e3e3e3e;
int l[maxn], r[maxn], a[maxn], n;
LL solve() {
LL res = 0;
l[0] = r[n + 1] = 0;
a[0] = a[n + 1] = INF;
for (int i = 1; i <= n; i++) {
l[i] = 1;
int t = i - 1;
while (a[i] <= a[t] && t >= 1) {
l[i] += l[t];
t -= l[t];
}
}
for (int i = n; i >= 1; i--) {
r[i] = 1;
int t = i + 1;
while (a[i] <= a[t] && t <= n) {
r[i] += r[t];
t += r[t];
}
}
for (int i = 1; i <= n; i++) {
LL t = (LL)a[i] * (LL)(l[i] + r[i] - 1);
res = max(res, t);
}
return res;
}
int main() {
while (scan(n) == 1 && n) {
for (int i = 1; i <= n; i++) scan(a[i]);
printf("%I64d\n", solve());
}
return 0;
}