51Nod - 1102 面积最大的矩形
Posted zhang--yd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; }
以上是关于51Nod - 1102 面积最大的矩形的主要内容,如果未能解决你的问题,请参考以下文章
51nod 1102 面积最大的矩形 && 新疆大学OJ 1387: B.HUAWEI's billboard 单调栈+拼凑段(o(n) 或 o(nlog(n))