51Nod - 1102 面积最大的矩形
51Nod - 1102 面积最大的矩形
有一个正整数的数组,化为直方图,求此直方图包含的最大矩形面积。例如 2,1,5,6,2,3,对应的直方图如下:

面积最大的矩形为5,6组成的宽度为2的矩形,面积为10。
Input
第1行:1个数N,表示数组的长度(0 <= N <= 50000) 第2 - N + 1行:数组元素A[i]。(1 <= A[i] <= 10^9)
Output
输出最大的矩形面积
Input示例
6 2 1 5 6 2 3
Output示例
10
题解:
(1), 第一种方法使用 rmq 的方法,建立线段树sparse table,然后再搜两端点找到最小值,扩充为该端点与之最小值的乘积。可是只ac了60%。
(2), 第二种方法是采用经典的 left_array 和 right_array 两个数组,找到每一个数组元素可以扩展到的最大值。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAXN = 50000 + 10;
int n, m, num[MAXN], dp[MAXN][30], dp_p[MAXN][30];
long long ans;
void build(){
for(int i=0; i<n; ++i){
dp[i][0] = num[i];
dp_p[i][0] = i;
}
for(int i=1; (1<<i)<=n; ++i){
for(int j=0; j+(1<<i)-1< n; ++j){
if(dp[j][i-1] > dp[j+(1<<(i-1))][i-1]){
dp[j][i] = dp[j+(1<<(i-1))][i-1];
dp_p[j][i] = dp_p[j+(1<<(i-1))][i-1];
}else{
dp[j][i] = dp[j][i-1];
dp_p[j][i] = dp_p[j][i-1];
}
}
}
}
void Search(int l, int r){
if(l >= r){
return;
}
int minv, min_j, k = (int)(log2(1.0*(r - l + 1)));
if(dp[l][k] < dp[r-(1<<k)+1][k]){
minv = dp[l][k];
min_j = dp_p[l][k];
}else{
minv = dp[r-(1<<k) + 1][k];
min_j = dp_p[r-(1<<k) + 1][k];
}
if(ans < (long long)(minv*(r - l + 1))){
ans = (long long)(minv * (r-l + 1));
}
Search(l, min_j - 1);
Search(min_j + 1, r);
}
int main(){
freopen("in.txt", "r", stdin);
while(scanf("%d", &n) != EOF){
ans = 0;
for(int i=0; i<n; ++i){
scanf("%d", &num[i]);
ans = max(ans, (long long)(num[i]));
}
build();
Search(0, n-1);
printf("%lld\n", ans );
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAXN = 50000 + 10;
long long ans, num[MAXN], l[MAXN], r[MAXN];
int main(){
int n, k, i;
scanf("%d", &n);
for(i=1; i<=n; ++i){
scanf("%lld", &num[i]);
}
num[0] = num[n+1] = 0;
for(i=1; i<=n; ++i){
k = i - 1;
while(num[i] <= num[k]){
k = l[k] - 1;
}
l[i] = k + 1;
}
for(i=n; i>=1; --i){
k = i + 1;
while(num[i] <= num[k]){
k = r[k] + 1;
}
r[i] = k - 1;
}
ans = 0;
for(i=1; i<=n; ++i){
if(ans < num[i]*(r[i] - l[i] + 1)){
ans = num[i]*(r[i] - l[i] + 1);
}
}
printf("%lld\n", ans);
return 0;
}

浙公网安备 33010602011771号