SCAU 算法设计与分析 9715 相邻最大矩形面积

9715 相邻最大矩形面积

Description

在X轴上水平放置着 N N N个条形图,这 N N N个条形图就组成了一个柱状图,每个条形图都是一个矩形,每个
矩形都有相同的宽度,均为 1 1 1单位长度,但是它们的高度并不相同。
例如下图,图1包含的矩形的高分别为 2 , 1 , 4 , 5 , 1 , 3 , 3 2,1,4,5,1,3,3 2145133单位长度,矩形的宽为 1 1 1单位长度。

在这里插入图片描述

你的任务就是计算柱状图中以 X X X轴为底边的最大矩形的面积。图2阴影部分就是上述例子的最大矩形面积。

输入格式

输入数据的第一行是一个整数 N(1≤ N ≤100000),表示柱状图包含 N 个矩形。
紧接着 N 个整数h1,…,hn(0≤ hi ≤20000, 1≤ i≤ N),表示柱状图中按从左到右顺序给出的矩形
的高度。矩形的宽度为1。

输出格式

输出一个整数S,表示以X轴为底边的最大矩形的面积。

输入样例

7
2 1 4 5 1 3 3

输出样例

8

思路:

  1. 首先题目给出提示为O(n 2)复杂度算法,计算最大矩形面积,考虑遍历每个单位矩形,双指针左右查看其延申的边界,然后取其中最大面积为答案。复杂度为O(n 2);
  2. 但数据N范围为1e5,有超时风险,考虑优化。观察到:其左右延申的距离最多至第一个小于其高的矩形处。问题转化为:求每个单位矩形,其左右第一个小于其高的矩形位置。答案为其延申宽度 乘以该单位矩形的高,再取最大值即可。
  3. 单调栈可以很好地解决该问题并把时间复杂度降低到O(n);

代码思路:

左右分两次跑一遍单调栈,其延申截止位置存储在l,r数组中(注意初始化),最后计算取max即可
tip:不了解单调栈的可以先去学习下其实现思路

//power by lxh #&10084
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#define int long long
using namespace std;
const int N = 2e6 + 7;
const int INF = 0x3f3f3f3f;
int n, m;
int s[N];
int r[N];
int l[N];
signed main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> s[i]; r[i] = n; l[i] = 1;
	}
	stack<int>st;
	for (int i = 1; i <=n; i++)
	{
		int now = s[i];
		while (st.size() && now < s[st.top()])
		{
			int hh = st.top();
			r[hh] = i - 1;//向右延申到此为止
			st.pop();
			
		}
		st.push(i);
	}
	stack<int>st1;
	for (int i = n; i > 0; i--)
	{
		int now = s[i];
		while (st1.size() && now < s[st1.top()])
		{
			int hh = st1.top();
			l[hh] = i + 1;//向左延申到此为止
			st1.pop();

		}
		st1.push(i);
	}
	int ans = 0;
	for (int i = 1; i <= n; i++)
		ans = max(ans, s[i] * (r[i] - l[i]+1));
	cout << ans << endl;
}


  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值