2021hdu多校1 Maximal submatrix(单调栈+简单dp)

**题意:**给你一个数字矩阵,让你找一个子矩阵,使其满足每一列是非递减的,输出最大的子矩阵的面积。
题解:

  1. 我们根据每一列进行非递减的dp,得到dp是以当前点为结尾的最大非降子序列。
  2. 然后根据我蓝书中一道单调栈的题(传送门),我们可以将每一行的dp当做矩形的高,矩形的宽为1,直接单调栈即可完成计算
    code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const double PI = acos(-1.0);
const int N = 2e3 + 50;
int dp1[N][N];
int a[N][N];
int n, m;
int s[N], w[N];
int solve()
{
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            dp1[i][j] = 0;
            scanf("%d", &a[i][j]);
        }
    for (int i = 1; i <= n; i++)
        dp1[i][m + 1] = 0;

    for (int j = 1; j <= m; j++)
        for (int i = 1; i <= n; i++)
        {

            if (a[i][j] >= a[i - 1][j])
            {
                dp1[i][j] = dp1[i - 1][j] + 1;
            }
            else
                dp1[i][j] = 1;
        }
    
    int ans = 0;
    int p = 0;
    for (int i = 1; i <= n; i++)
    {
        p = 0;
        for (int j = 1; j <= m + 1; j++)
        {
            if (dp1[i][j] > s[p])
            {
                s[++p] = dp1[i][j];
                w[p] = 1;
            }
            else
            {
                int width = 0;
                while (s[p] > dp1[i][j])
                {
                    width += w[p];
                    ans = max(ans, width * s[p]);
                    p--;
                }
                s[++p] = dp1[i][j], w[p] = width + 1;
            }
        }
    }
    return ans;
}
int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d%d", &n, &m);
        printf("%d\n", solve());
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值