洛谷P1736_和p1387一样的套路

维护向左,向上和向对角线扩展的最大值

然后去三个方向的最小值然后加1

************************************************************************************************

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

using namespace std;

const int maxn = 2510;

int a[maxn][maxn];
int dp[maxn][maxn];//在对角线方向扩展的最大1
int verti[maxn][maxn], level[maxn][maxn];//在垂直/水平方向最多扩展的0

int m, n;

int main()
{
    int i, j;
    scanf("%d %d", &m, &n);
    memset(dp, 0, sizeof(dp));
    memset(verti, 0, sizeof(verti));
    memset(level, 0, sizeof(level));
    int ans = 0;
    //左上到右下
    for(i = 1; i <= m; ++i)
        for(j = 1; j <= n; ++j)
    {
        scanf("%d", &a[i][j]);
        if(!a[i][j])
        {
            verti[i][j] = verti[i-1][j]+1;
            level[i][j] = level[i][j-1]+1;
        }
        else
        {
            dp[i][j] = min(dp[i-1][j-1], min(verti[i-1][j], level[i][j-1]))+1;
            ans = max(ans, dp[i][j]);
        }
    }
    //右上到左下
    memset(dp, 0, sizeof(dp));
    memset(verti, 0, sizeof(verti));
    memset(level, 0, sizeof(level));
    for(i = 1; i <= m; ++i)
        for(j = n; j >= 1; --j)
    {
        if(!a[i][j])
        {
            verti[i][j] = verti[i-1][j]+1;
            level[i][j] = level[i][j+1]+1;
        }
        else
        {
            dp[i][j] = min(dp[i-1][j+1], min(verti[i-1][j], level[i][j+1]))+1;
            ans = max(ans, dp[i][j]);
        }
    }
    printf("%d\n", ans);
    return 0;
}


猜你喜欢

转载自blog.csdn.net/jay__bryant/article/details/80152801