CCF-201312-3(最大的矩形)

								 最大矩形

一:题目描述

在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤ i ≤ n)个矩形的高度是hi。这n个矩形构成了一个直方图。例如,下图中六个矩形的高度就分别是3, 1, 6, 5, 2, 3。

请找出能放在给定直方图里面积最大的矩形,它的边要与坐标轴平行。对于上面给出的例子,最大矩形如下图所示的阴影部分,面积是10。

二:理解
①.法一:暴力法
开始这道题用了一下暴力,便利了所有的元素,比如[2, 1, 5, 6, 2, 3],遍历所有右区间[2], [2, 1], [2, 1, 5], …, [2, 1, 5, 6, 2, 3], [1], [1, 5], [1, 5, 6], …, [1, 5, 6, 2, 3], [5], [5, 6], …, [5, 6, 2, 3], …, [3],得到各自的矩阵面积,返回最大值。
时间复杂度为O(n^2),提交了一下,没过(时间问题)。

代码跑了一下,是没有问题的:

#include<bits/stdc++.h>
#include<iostream>

using namespace std;

int n;  //矩阵的个数
int num[1005];  //矩阵的高度

//暴力 
int main()
{
	int count = 0;
	cin >> n;
	for(int i = 0; i < n; i++)
		cin >> num[i];
	for(int i = 0; i < n; i++)
	{
		int minnum = 10005;
		for(int j = i; j < n; j++)
		{
			if(minnum > num[j])
				minnum = num[j];   //找最小的矩阵高
			count = max(count, (minnum * (j - i + 1))); //矩阵个数乘以矩阵最小高度
		}
	}
	cout << count;
	return 0;
}

代码解释:这个纯暴力就是上面介绍的那样实现;应该比较好理解!
结果:

②.单调栈算法(时间复杂度为 O(n),借助单调性处理问题的思想在于即使排除不可能的选项,保持策略集合的高度有效性和秩序性,从而为我们做出决策提供更多的条件和可能方法。)
思路:
建立一个栈,保存若干个矩形,并且栈顶元素到栈底元素始终由大到小(一直保持的形式)。我们从左到右依次扫描每一个矩形: 如果当前矩形比栈顶矩形高,直接进栈;否则不断取出栈顶,直至栈为空或者栈顶矩形的高度比当前最后一个矩形小。
在出栈过程中,我们累计被弹出的矩形的宽度之和,并且每弹出一个矩形,就用它的高度乘上累积的宽度更新答案。整个出栈过程结束后,我们把高度作为当前矩形的高度、宽度为累计值的新矩形入栈。
整个扫描结束后,我们把栈中剩余的矩形依次弹出,按照与上面相同的办法更新答案。

代码:

#include<bits/stdc++.h>
using namespace std;

//变量 
int n;
int num[1010],numstack[1010],weight[1010];
//单调栈
int main()
{	
	int temp = 0;
	long long count = 0;
	cin >> n;
	for(int i = 0; i < n; i++)
		cin >> num[i];
	for(int i = 0; i <= n; i++)
	{
		if(num[i] > numstack[temp])
		{
			numstack[++temp] = num[i];
			weight[temp] = 1;
		}
		else
		{
			int maxwidth = 0;
			while(num[i] < numstack[temp])
			{
				maxwidth+=weight[temp];
				count = max(count,(long long)maxwidth*numstack[temp--]);
			}
			numstack[++temp] = num[i];
			weight[temp] = maxwidth + 1;
		}
	}
	cout << count << endl;
	return 0;
}
发布了89 篇原创文章 · 获赞 90 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/pfl_327/article/details/103990021
今日推荐