题意理解
求m×n矩阵中,每个元素取值只有0,1,求元素1组成的最大正方形面积
问题分析
用动规
状态量:以每个元素为右下角的矩阵的最大边长
转移方程:对于a[i][j], dp[i][j] = min(dp[i-1][j], dp[i][j-1],dp[i-1][j-1]) + 1;表示对于每个非0的矩阵元素,计算它相邻的左元素,上元素和左对角线对应的最大边长的最小值 + 1。
其他
动规很有用。这是经典题。
0805:忘记了只考虑等于1的情况,忘记了求的是面积,而dp是边长,忘记了求最大值,而不是最后一个值。
链接
int maximalSquare(vector<vector<char>>& matrix) {
if (!matrix.size())
return 0;
if (!matrix[0].size())
return 0;
int m = matrix.size();
int n = matrix[0].size();
int dp[m][n] = {0};
for (int i = 0; i != m; i ++) //初始化第一列
{
if (matrix[i][0] == '1')
dp[i][0] = 1;
else
dp[i][0] = 0;
}
for (int j = 0; j != n; j ++) //初始化第一行
{
if (matrix[0][j] == '1')
dp[0][j] = 1;
else
dp[0][j] = 0;
}
cout << "m n " << m << '\t' << n << endl;
for (int i = 1; i != m; i ++)
{
for (int j = 1; j != n; j ++)
{
if (matrix[i][j] == '1') //对于每个非0的位置
{
int tmp = min(dp[i - 1][j], dp[i][j - 1]); //计算左,上,右位置边长的最小值
dp[i][j] = min(dp[i - 1][j - 1], tmp) + 1; //再加上(自身)
cout << "i j " << i << '\t' << j << '\t' << dp[i][j] << endl;
}
}
}
int max = 0;
for (int i = 0; i != m; i ++) //取最大值
{
for (int j = 0; j != n; j ++)
{
if (dp[i][j] > max)
max = dp[i][j];
}
}
return max * max; //边长平方等于面积
}