单调栈:最大矩形. c++

最大矩形

在这里插入图片描述
输入包含多组数据。每组数据用一个整数n来表示直方图中小矩形的个数,可以假定1 <= n <= 100000. 然后接下来n个整数h1, …, hn, 满足 0 <= hi <= 1000000000. 这些数字表示直方图中从左到右每个小矩形的高度,每个小矩形的宽度为1。 测试数据以0结尾。对于每组测试数据输出一行一个整数表示答案。

sample input:
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0

sample output:
8
4000

思路:

  • 显然最终的矩形大小=宽×高,高是一个矩形的高度,宽是这个矩形左至右遇到第一个比他矮的矩形所经过的矩形个数
  • 根据这个思路其实可以用暴力,针对每一个矩形都向他的左右去寻找比他小的矩形,然后进行计算经过的宽度,但是由于给定的数据个数较多,可能会爆
  • 对两边进行寻找比较麻烦,如果能首先将矩形进行从低到高的排列,那么只需要计算他的右边有多少个矩形,就可以算出当前的矩形面积。(因为低矩形不能计算宽度,这样就可以从双边变成单边)
  • 这样就可以使用单调栈的思想,建立一个栈,栈内保存的矩形是高度递增的。为了到达目的,遍历每一个直方图矩形:如果当前矩形的高度比栈顶矩形的高度高,那么就将当前高度压栈;否则就弹出栈顶。
  • 出栈时计算出累计的宽度值,计算出矩形的大小与答案进行比较,取较大值对答案进行更新;再将累计宽度和当前高度存入,进行压栈。
  • 全部遍历后得到的ans就是最大的矩形面积,单调栈的时间复杂度只有O(n)
  • 第一次使用了stack类型直接做,然后TLE了,所以用数组进行描述,添加一个int变量top相当于栈顶。需要注意的是本题的数据范围,ans和stack需要使用long long ,在max比较的时候需要将比较的变量化成统一数据类型,强制类型转换即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
using namespace std;
int main()
{
 int n;
 while(scanf("%d",&n)!=EOF&&n!=0)
 {
 int a[100011],w[100011];
 long long stack[100011];
 long long top=0;
 long long ans=0;
 memset(a,0,sizeof(a));
 for(int i=0;i<n;i++) scanf("%d",&a[i]);
 for(int i=0;i<=n;i++)
 {
  if(a[i]>stack[top])
  {
   stack[++top]=a[i];
   w[top]=1; 
  }
  else
  {
   int width=0;
   while(stack[top]>a[i])
   {
    width+=w[top];
    ans=max(ans,(long long)width*stack[top]);
    top--;
   }
   top++;
   stack[top]=a[i];
   w[top]=width+1;
  }
 }
 printf("%lld\n",ans);
 } 
 return 0;
 } 
发布了29 篇原创文章 · 获赞 1 · 访问量 941

猜你喜欢

转载自blog.csdn.net/qq_44654498/article/details/104973739