问题陈述就像这样
给定二进制矩阵,找出所有1的最大尺寸方形子矩阵。
例如,请考虑以下二进制矩阵。
0 1 1 0 1
1 1 0 1 0
0 1 1 1 0
1 1 1 1 0
1 1 1 1 1
0 0 0 0 0
具有所有设置位的最大平方子矩阵是3
我创建了一个基于memoization的dp解决方案
我的节目是
#include<bits/stdc++.h>
using namespace std;
#define R 6
#define C 5
int getmaxsizesummatrix(int mat[R][C],vector< vector<int> > &v,int r,int c)
{
if(r<0||c<0)
return 0;
if(r==0||c==0)
{
v[r][c]=mat[r][c];
return mat[r][c];
}
if(v[r][c]==-1)
{
int m=INT_MIN;
int flag=1;
for(int j=0;j<=r;j++)
{
for(int k=0;k<=c;k++)
{
int x,y,z;
x = getmaxsizesummatrix(mat,v,j-1,k-1);
y = getmaxsizesummatrix(mat,v,j-1,k);
z = getmaxsizesummatrix(mat,v,j,k-1);
if(mat[j][k]==1)
{
m=max(m,min(x,min(y,z))+1);
}
else
{
m=max(m,min(x,min(y,z)));
}
}
}
return v[r][c] = m;
}
else
{
return v[r][c];
}
}
int main()
{
int M[R][C] = {{0, 1, 1, 0, 1},
{1, 1, 0, 1, 0},
{0, 1, 1, 1, 0},
{1, 1, 1, 1, 0},
{1, 1, 1, 1, 1},
{0, 0, 0, 0, 0}};
vector< vector<int> > v(R+1,vector<int>(C+1,-1));
cout<<getmaxsizesummatrix(M,v,6,5);
return 0;
}
我得到4作为输出。
任何人都可以纠正我的做法吗?
答案 0 :(得分:0)
不确定这一点,但从它的外观来看 - 你是一个人。
注意:
#define R 6
#define C 5
...
int M[R][C] = {...};
getmaxsizesummatrix(M,v,6,5);
...
int getmaxsizesummatrix(int mat[R][C],vector< vector<int> > &v,int r,int c) // r=6, c=5
{
...
for(int j=0;j<=r;j++)
{
for(int k=0;k<=c;k++)
{
...
}
}
}
或许解决方案是严格检查j<r
而不是j<=r
。
答案 1 :(得分:0)
我已经修改了一些代码以使其正常工作
以下是解释:实施DP解决方案时遇到2个问题
v[][]
对于<
vs <=
作为提及的其他答案,这不是您实施中的问题,因为它是异常实现,如上面第2点所述,但你必须通过R-1
&amp; C-1
代替函数,因此您仍然可以在不超出约束的情况下计算v[r][c]
我将重点关注以上两点。
对于1,你能告诉我你对v[][]
的定义是什么吗?
它是到目前为止找到的最大方形长度或方形的右下角是(i,j)的最大方形长度?这是一个巨大的选择差异,当您使用v[][]
递归计算另一个v[][]
时,您应该采用第二个选项,这是我为您修改的代码的一部分。例如,您的代码会在1
(从0开始)时提供v[1][2] & v[1][4]
,而我的0
将mat[1][2] & mat[1][4]
为0
并且不能形成任何方格。修改后,现在您的代码将计算采用第二个定义的v[][]
,因此我们必须遍历整个v[][]
以获得答案,而不是简单地打印v[R][C]
对于2,你的实现有点混乱,因为你混淆了自下而上&amp;自上而下的实施。换句话说,你混淆了 for-loop迭代&amp; 递归,对于包括此问题在内的大多数DP问题,您只需选择一种方法,但不能同时选择两种方法。您正在尝试递归方法,它会调用Function(R,C)
来获得答案,但在每次调用中,您每次都会循环遍历数组,这是冗余且容易出错的。你应该
v[][]
Func(R,C) = max(Func(R-1,C-1), Func(R-1,C), Func(R,C-1))+1
的基本案例来保护负面索引,已计算v[r][c]
等。请查看代码并告诉我是否遗漏或不清楚,如果需要,我会解释更多。
#include<bits/stdc++.h>
using namespace std;
#define R 6
#define C 5
int getmaxsizesummatrix(int mat[R][C],vector< vector<int> > &v,int r,int c)
{
if(r<0||c<0)
return 0;
if(r==0||c==0)
{
v[r][c]=mat[r][c];
return mat[r][c];
}
if(v[r][c]==-1)
{
int m=INT_MIN;
for(int j=0;j<=r;j++)
{
for(int k=0;k<=c;k++)
{
int x,y,z;
x = getmaxsizesummatrix(mat,v,j-1,k-1);
y = getmaxsizesummatrix(mat,v,j-1,k);
z = getmaxsizesummatrix(mat,v,j,k-1);
if(mat[j][k]==1)
{
m=max(m,min(x,min(y,z))+1);
}
else
{
m=max(m,min(x,min(y,z)));
}
}
}
if(mat[r][c] == 0) return v[r][c] = 0; // <-- Add this line
return v[r][c] = m;
}
else
{
return v[r][c];
}
}
int main()
{
int M[R][C] = {{0, 1, 1, 0, 1},
{1, 1, 0, 1, 0},
{0, 1, 1, 1, 0},
{1, 1, 1, 1, 0},
{1, 1, 1, 1, 1},
{0, 0, 0, 0, 0}};
vector< vector<int> > v(R+1,vector<int>(C+1,-1));
getmaxsizesummatrix(M,v,R-1,C-1); // <-- Change Parameter
// Change the answer-optain code
int ans = INT_MIN;
for(int i=0; i<R; i++)
for(int j=0; j<C;j++) ans = max(ans, v[i][j]);
cout << ans << endl;
return 0;
}