维护向左,向上和向对角线扩展的最大值
然后去三个方向的最小值然后加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; }