zoukankan      html  css  js  c++  java
  • 2021“MINIEYE杯”中国大学生算法设计超级联赛(1)1008.Maximal submatrix

    Maximal submatrix

    题目链接

    https://acm.hdu.edu.cn/showproblem.php?pid=6957

    题意

    给定一个 (n)(m) 列的矩阵,求每个列上不递减的最大面积子矩阵

    思路

    (sum[i][j]) 为第 (i) 行第 (j) 列从上往下以 (a[i][j]) 结尾的最长不递减序列长度,枚举每一个 (sum[i][j]) 作为列的最长长度, 显然行长度只能延伸到左右第一个小于 (sum[i][j]) 的位置之前,用单调栈维护即可。

    AC_Code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e3 + 50;
    int mp[maxn][maxn];
    int sum[maxn][maxn];
    int st[maxn], Lmin[maxn], Rmin[maxn], b[maxn];
    void getLmin(int a[], int n){//左边第一个小于a[i]的数
        int cnt = 0;
        st[0] = 0;
        for(int i = 1;i <= n;i++){
            while(cnt && a[i] <= a[st[cnt]]) cnt--;
            Lmin[i] = st[cnt];
            st[++cnt] = i;
        }
    }
    void getRmin(int a[], int n){//右边第一个小于a[i]的数
        int cnt = 0;
        st[0] = n + 1;
        for(int i = n;i >= 1;i--){
            while(cnt && a[i] <= a[st[cnt]]) cnt--;
            Rmin[i] = st[cnt];
            st[++cnt] = i;
        }
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        int t;
        cin >> t;
        while(t--){
            int n, m;
            cin >> n >> m;
            for(int i = 0;i <= n + 1;i++)
                for(int j = 0;j <= m + 1;j ++){
                    mp[i][j] = sum[i][j] = 0;
                }
            for(int i = 1;i <= n;i++){
                for(int j = 1;j <= m;j++){
                    cin >> mp[i][j];
                }
            }
    
            for(int i = 1;i <= n;i++){
                for(int j = 1;j <= m;j++){
                    if(mp[i][j] >= mp[i - 1][j]) sum[i][j] = sum[i - 1][j] + 1;
                    else sum[i][j] = 1;
                }
            }
            int ans = 0;
            for(int i = 1;i <= n;i++){
                for(int j = 1;j <= m;j++){
                    b[j] = sum[i][j];
                }
                getLmin(b, m);
                getRmin(b, m);
                for(int j = 1;j <= m;j++){
                    ans = max(ans, sum[i][j] * ( (Rmin[j] - 1) - (Lmin[j] + 1) + 1));
                }
            }
            cout << ans << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    670. Maximum Swap
    653. Two Sum IV
    639. Decode Ways II
    636. Exclusive Time of Functions
    621. Task Scheduler
    572. Subtree of Another Tree
    554. Brick Wall
    543. Diameter of Binary Tree
    535. Encode and Decode TinyURL
    博客园自定义背景图片
  • 原文地址:https://www.cnblogs.com/Carered/p/15040979.html
Copyright © 2011-2022 走看看