hdu - 2870 - Largest Submatrix(dp / 单调栈)

来源:互联网 发布:淘宝兼职平面模特 编辑:程序博客网 时间:2024/05/22 06:50

题意:一个由 a, b, c, w, x, y, z 组成的 m 行 n 列(1 ≤ m, n ≤ 1000)的字母矩阵,w 可以转成 a, b,x 可以转成 b, c,y 可以转成 a, c,z 可以转成 a, b, c。问由相同字母组成的最大子矩阵的面积。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2870

——>>依次求a, b, c的最大子矩阵。。

求一个矩阵的最大子矩阵:http://blog.csdn.net/scnu_jiechao/article/details/40677547

#include <cstdio>#include <cstring>#include <algorithm>using std::max;const int MAXN = 1000 + 10;int m, n;int ret;int h[MAXN];int L[MAXN], R[MAXN];char G[MAXN][MAXN];void Read(){    for (int i = 1; i <= m; ++i)    {        getchar();        for (int j = 1; j <= n; ++j)        {            G[i][j] = getchar();        }    }}void Init(){    ret = 0;}void Dp(){    for (int i = 1; i <= n; ++i)    {        L[i] = i;        while (L[i] - 1 >= 1 && h[L[i] - 1] >= h[i])        {            L[i] = L[L[i] - 1];        }    }    for (int i = n; i >= 1; --i)    {        R[i] = i;        while (R[i] + 1 <= n && h[R[i] + 1] >= h[i])        {            R[i] = R[R[i] + 1];        }    }    for (int i = 1; i <= n; ++i)    {        ret = max(ret, (R[i] - L[i] + 1) * h[i]);    }}void GetTargetMax(char target, char c1, char c2, char c3){    memset(h, 0, sizeof(h));    for (int i = 1; i <= m; ++i)    {        for (int j = 1; j <= n; ++j)        {            char& x = G[i][j];            if (x == target || x == c1 || x == c2 || x == c3)            {                ++h[j];            }            else            {                h[j] = 0;            }        }        Dp();    }}void Output(){    printf("%d\n", ret);}int main(){    while (scanf("%d%d", &m, &n) == 2)    {        Read();        Init();        GetTargetMax('a', 'w', 'y', 'z');        GetTargetMax('b', 'w', 'x', 'z');        GetTargetMax('c', 'x', 'y', 'z');        Output();    }    return 0;}

单调栈实现:

#include <cstdio>#include <cstring>#include <algorithm>using std::max;const int MAXN = 1000 + 10;int m, n;int ret;int h[MAXN];int L[MAXN], R[MAXN];char G[MAXN][MAXN];struct MS{    int st[MAXN];    int top;    MS(): top(0) {}    void Init()    {        top = 0;    }    void PushMin(const int* A, const int& i)    {        while (top != 0 && A[i] <= A[st[top - 1]])        {            --top;        }        st[top++] = i;    }    int Size()    {        return top;    }    int Second()    {        return st[top - 2];    }};void Read(){    for (int i = 1; i <= m; ++i)    {        getchar();        for (int j = 1; j <= n; ++j)        {            G[i][j] = getchar();        }    }}void Init(){    ret = 0;}void Update(){    MS ms;    for (int i = 1; i <= n; ++i)    {        ms.PushMin(h, i);        if (ms.Size() == 1)        {            L[i] = 1;        }        else        {            L[i] = ms.Second() + 1;        }    }    ms.Init();    for (int i = n; i >= 1; --i)    {        ms.PushMin(h, i);        if (ms.Size() == 1)        {            R[i] = n;        }        else        {            R[i] = ms.Second() - 1;        }    }    for (int i = 1; i <= n; ++i)    {        ret = max(ret, (R[i] - L[i] + 1) * h[i]);    }}void GetTargetMax(char target, char c1, char c2, char c3){    memset(h, 0, sizeof(h));    for (int i = 1; i <= m; ++i)    {        for (int j = 1; j <= n; ++j)        {            char& x = G[i][j];            if (x == target || x == c1 || x == c2 || x == c3)            {                ++h[j];            }            else            {                h[j] = 0;            }        }        Update();    }}void Output(){    printf("%d\n", ret);}int main(){    while (scanf("%d%d", &m, &n) == 2)    {        Read();        Init();        GetTargetMax('a', 'w', 'y', 'z');        GetTargetMax('b', 'w', 'x', 'z');        GetTargetMax('c', 'x', 'y', 'z');        Output();    }    return 0;}


0 0
原创粉丝点击