题解 P1681 【最大正方形II】
惊! 在题解里竟然没有我的做法(汗-_-||
本蒟蒻来谈谈我的做法
这道题就是最大正方形的变式;
最大正方形那道题,是设dp[i][j]为在(i,j)以上的最大正方形;
本题就是多加了一个条件,满足黑白相间的最大正方形;
所以可以多设一维表示此位置是1还是0;
就有了dp[i][j][0/1] 表示在(i, j)以上, 且本位是0/1的最大符合条件的正方形;
转移方程:
如果本位是1: f[i][j][1] = min(f[i-1][j][0], min(f[i][j-1][0], f[i-1][j-1][1])) + 1
如果是0: f[i][j][0] = min(f[i-1][j][1], min(f[i][j-1][1], f[i-1][j-1][0])) + 1
然后每步后取max就行了;
代码:
#include <bits/stdc++.h>
using namespace std;
int f[1501][1501][2];
int n, m, a[1505][1505];
int ans = -1;
inline int read()
{
int X=0,w=0;char ch=0;
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
int main()
{
n = read(), m = read();
for(register int i=1;i<=n;i++)
{
for(register int j=1;j<=m;j++)
{
a[i][j] = read();
}
}
for(register int i=1;i<=n;i++)
{
for(register int j=1;j<=m;j++)
{
if(a[i][j] == 1) f[i][j][1] = min(f[i-1][j][0], min(f[i][j-1][0], f[i-1][j-1][1])) + 1, ans = max(ans, f[i][j][1]);
if(a[i][j] == 0) f[i][j][0] = min(f[i-1][j][1], min(f[i][j-1][1], f[i-1][j-1][0])) + 1, ans = max(ans, f[i][j][0]);
}
}
printf("%d",ans);
return 0;
}