[51Nod] (1102) 面积最大的矩形 ---- 单调栈(思维)

版权声明:本文为博主原创文章,转载请预先通知博主(〃▽〃)。 https://blog.csdn.net/m0_37624640/article/details/84202222

题目传送门

思路:

  • 自己的想法跟题解一样,也是从左右两边找到最远能扩展的位置。但这样复杂度一定是O(n^2)
  • 显然会超时,于是自己发现除了这个思路没有好办法了,于是去学习一波新技能√ ---- 单调栈!
  • 单调栈其实精湛的不是用栈去实现,而是一种思维,用这种单调的思维去降低复杂度。
  • 以这个题为例,我们可以给每个位置pos,记录它向右最远的扩展距离R[pos],向左最远的扩展距离L[pos]。
  • 举个栗子:
  • 如果从位置i 想左进行扩展,第一个index = i-1,如果val[index]>=val[i],证明可以继续向左扩展,这时候index不需要向前走一步,而是走l[index]步,中间的这些一定也是>=val[i]的。即是单调的!酱紫就少了很多冗余的判断,使得整个过程几乎是单调的。这就是单调栈精髓的地方!
  • 所以我们预处理好每个位置,然后找到max(l[i]+r[i]+1)*val[i] 即可

AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define IO          ios_base::sync_with_stdio(0),cin.tie(0)
#define pb(x)       push_back(x)
#define sz(x)       (int)(x).size()
#define abs(x)      ((x) < 0 ? -(x) : x)
#define mk(x,y)     make_pair(x,y)
#define fin         freopen("in.txt","r",stdin)
#define fout        freopen("out.txt","w",stdout)

typedef long long ll;
typedef pair<int,int> P;
const int mod = 1e9+7;
const int maxm = 1e8+5;
const int maxn = 1e5+5;
const int INF = 0x3f3f3f3f;
const ll LINF = 1ll<<62;

ll a[maxn];
ll l[maxn];
ll r[maxn];
int main()
{
//    fin;
//    IO;
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        for(int i=1;i<=n;i++){
            int index = i-1;
            l[i] = 1;
            while(a[i]<=a[index] && index>=1){
                l[i]+=l[index];
                index-=l[index];
            }
        }
        for(int i=n;i>=1;i--){
            int index = i+1;
            r[i] = 1;
            while(a[i]<=a[index] && index<=n)
            {
                r[i]+=r[index];
                index+=r[index];
            }
        }
        ll res = 0;
        for(int i=1;i<=n;i++){
            res = max(a[i]*(l[i]+r[i]-1),res);
        }
        printf("%lld\n",res);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37624640/article/details/84202222