Largest Rectangle in a Histogram(单调栈)

发布于 2022-02-27  681 次阅读


题目链接:Largest Rectangle in a Histogram (nowcoder.com)

题目难度3星,做法比较多,稍微优化一下的暴力枚举也能过,这里写一下单调栈的做法。

题目大意

给一个类似条形统计图的东西,每个点有各自的高度,求可以从中截取的最大矩形面积。

思路

有可能是最大矩形的矩形其实就是各个点的高度,向左右延伸最长距离得到的。

那么就遍历每个点,向左右延伸,直到遇到比该点更小的点就停止

不难发现,这又是有方向的遍历且有明确的大小关系,所以考虑用单调栈,之前这道题《[USACO 2006 Nov S]Bad Hair Day(单调栈) – ErikTse Runtime》也用了单调栈。

代码

/* Copyright (C) 2022 ErikTse */
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#include <utility>
#include <stack>
#include <algorithm>
#define pb push_back
#define fi first
#define se second
#define pr printf
#define sc scanf
#define gc getchar
#define int long long
//请使用%lld输出long long类型数据
using namespace std;
inline int re(){
	int s = 0,w = 1;char c = gc();
	while(c > '9' || c < '0'){if(c == '-')w = -1;c = gc();}
	while('0' <= c && c <= '9'){s = s * 10 + c - '0',c = gc();}
	return s * w;
}
/*-------全局变量------*/
typedef pair<int, int> PII;
const int maxn = 1e5 + 10;
int h[maxn];//存高度 
int sq[maxn];//存下该点向左右延伸的最大面积 
PII stk[maxn];//{位置,高度}
int N, top = 0;


/*-----自定义函数------*/
inline void solve()
{
	for(int i = 1;i <= N; ++ i)h[i] = re();
	h[N + 1] = 0;//最后一个设置为 0 是为了将所有元素都出栈算出可能的面积 
	top = 0;
	memset(sq, 0, sizeof sq);
	//其实这里高度可以不用存储 
	for(int i = 1;i <= N + 1; ++ i)
	{
		while(top && stk[top].se >= h[i])//如果h[i] <= 栈顶高度,说明栈顶元素右边边界就是 i 
		{
			sq[stk[top].fi] += (i - stk[top].fi) * stk[top].se;//注意算面积左闭右开 
			top --;
		}
		sq[i] += (i - stk[top].fi - 1) * h[i];//因为是单调递增栈,所以 i 左边界就是栈顶 
		stk[++ top] = {i, h[i]};//入栈 
	}
	int ans = 0;
	for(int i = 1;i <= N; ++ i)ans = max(ans, sq[i]);
	pr("%lld\n",ans);
	return;
}

signed main()
{
	//freopen("in.txt","r",stdin);
	while(cin >> N && N != 0)solve();
	return 0;
}


19岁,性别未知,ACM-XCPC退役选手,CCPC全国邀请赛金牌,ICPC亚洲区域赛银牌,武汉某院校计算机科学与技术专业本科在读。
最后更新于 2022-07-09