1 条题解
-
1
解决这个问题之前我们先讲一个新知识点,对于一行连续的柱形图,如何求出最大的矩形面积。
设当前柱形高度为 , 为当前元素左边第一个高度小于它的柱形的位置, 为右边第一个,计 为扩展出的矩形的面积 ,最终答案为所有的 取最大。
/** * author: 小飞侠 * created: 2024.12.11 15:59:04 */ #include <iostream> using namespace std; const int N = 3010; int l[N], r[N], q[N]; int g[N][N], h[N][N]; int n, m, p; int res; int cal(int h[])//计算这一行为底的最大矩形面积 { int top = 0; l[0] = -1, h[m + 1] = -1; for(int i = 1; i <= m; ++ i) { while(top && h[q[top]] >= h[i]) -- top; if(!top) l[i] = 0; else l[i] = q[top]; q[++ top] = i; }//l[m]存储 m 个元素左边第一个小于他的元素的位置 top = 0; for(int i = m; i >= 1; -- i) { while(top && h[q[top]] >= h[i]) -- top; if(!top) r[i] = m + 1; else r[i] = q[top]; q[++ top] = i; }//r[m]存储 m 个元素右边第一个小于他的元素的位置 int res = 0; for(int i = 1; i <= m; ++ i) res = max(res, (r[i] - l[i] - 1) * h[i]);//所有的 t return res; } int main() { cin >> n >> m >> p; while(p --) { int x, y; cin >> x >> y; g[x][y] = 1; } for(int i = 1; i <= n; ++ i) { for(int j = 1; j <= m; ++ j) { if(!g[i][j]) h[i][j] = h[i - 1][j] + 1; } }//用 h 数组模拟出柱形图 //h[i] 这一行数表示的是第 i 行为底的柱形图每一列的高度 for(int i = 1; i <= n; ++ i) res = max(res, cal(h[i]));//暴力枚举任意一行为底部的柱形图 cout << res << '\n'; return 0; }
- 1
信息
- ID
- 5520
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 8
- 已通过
- 2
- 上传者