zoukankan      html  css  js  c++  java
  • HDU4328 Cut the cake(动规:最大子矩形问题/悬线法)

    题目链接:传送门

    题目大意:

      给出N*M的字符矩阵(由字符B/R组成),求符合下图条件的子矩阵的最大周长。

      1 ≤ N,M ≤ 1000。

                           

    思路:

      悬线法。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    const int MAX_N = 1e3 + 5;
    
    int N, M;
    char mat[MAX_N][MAX_N];
    int lef[MAX_N][MAX_N], rig[MAX_N][MAX_N], up[MAX_N][MAX_N];
    
    void init1()
    {
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++)
                if (j > 1 && mat[i][j] == mat[i][j-1])
                    lef[i][j] = lef[i][j-1] + 1;
                else
                    lef[i][j] = 1;
            for (int j = M; j >= 1; j--)
                if (j < M && mat[i][j] == mat[i][j+1])
                    rig[i][j] = rig[i][j+1] + 1;
                else
                    rig[i][j] = 1;
        }
    }
    
    void init2()
    {
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++)
                if (j > 1 && mat[i][j] != mat[i][j-1])
                    lef[i][j] = lef[i][j-1] + 1;
                else
                    lef[i][j] = 1;
            for (int j = M; j >= 1; j--)
                if (j < M && mat[i][j] != mat[i][j+1])
                    rig[i][j] = rig[i][j+1] + 1;
                else
                    rig[i][j] = 1;
        }
    }
    
    int dp1()
    {
        int ans = 0;
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++) {
                if (i > 1 && mat[i][j] == mat[i-1][j]) {
                    up[i][j] = up[i-1][j] + 1;
                    lef[i][j] = min(lef[i][j], lef[i-1][j]);
                    rig[i][j] = min(rig[i][j], rig[i-1][j]);
                }
                else
                    up[i][j] = 1;
                int len = lef[i][j] + rig[i][j] - 1;
                int high = up[i][j];
                ans = max(ans, 2*len+2*high);
            }
        }
        return ans;
    }
    
    int dp2()
    {
        int ans = 0;
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++) {
                if (i > 1 && mat[i][j] != mat[i-1][j]) {
                    up[i][j] = up[i-1][j] + 1;
                    lef[i][j] = min(lef[i][j], lef[i-1][j]);
                    rig[i][j] = min(rig[i][j], rig[i-1][j]);
                }
                else
                    up[i][j] = 1;
                int len = lef[i][j] + rig[i][j] - 1;
                int high = up[i][j];
                ans = max(ans, 2*len + 2*high);
            }
        }
        return ans;
    }
    
    int main()
    {
        int T;
        int kase = 1;
        cin >> T;
        while (T--) {
            cin >> N >> M;
            for (int i = 1; i <= N; i++)
                for (int j = 1; j <= M; j++)
                    cin >> mat[i][j];
            int ans = 1;
            init1();
            ans = max(ans, dp1());
            init2();
            ans = max(ans, dp2());
            printf("Case #%d: %d
    ", kase++, ans);
        }
        return 0;
    }
    /*
    2
    3 3
    BBR
    RBB
    BBB
    1 1
    B
    */
    View Code
  • 相关阅读:
    httpd-2.2 配置及用法完全攻略
    在 Ubuntu 16.04 上安装 LEMP 环境之图文向导
    Zookeeper集群搭建
    smem – Linux 内存监视软件
    X.Org可能将失去它的域名x.org
    Docker 容器测试全探索
    Unix操作系统中UUCP知识详细讲解
    常用的Git Tips
    Unix操作系统中UUCP知识详细讲解
    将博客搬至CSDN
  • 原文地址:https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/9838212.html
Copyright © 2011-2022 走看看