原题链接
P1387
题目类型:
普
及
/
提
高
−
{\color{yellow} 普及/提高-}
普及/提高−
AC记录:Accepted
题目大意
在一个 n × m n\times m n×m的只包含 0 0 0和 1 1 1的矩阵里找出一个不包含 0 0 0的最大正方形,输出边长。
输入格式
输入文件第一行为两个整数 n , m n,m n,m,接下来 n n n行,每行 m m m个数字,用空格隔开, 0 0 0或 1 1 1。
输出格式
一个整数,最大正方形的边长
S a m p l e \mathbf{Sample} Sample I n p u t \mathbf{Input} Input
4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1
S a m p l e \mathbf{Sample} Sample O u t p u t \mathbf{Output} Output
2
H
i
n
t
&
E
x
p
l
a
i
n
\mathbf{Hint\&Explain}
Hint&Explain
无
数据范围
对于 100 % 100\% 100%的数据, 1 ≤ n , m ≤ 100 1\le n,m\le 100 1≤n,m≤100。
解题思路
一看就是道
d
p
dp
dp题目。
设
a
a
a为原矩阵,
f
i
,
j
f_{i,j}
fi,j为以
(
i
,
j
)
(i,j)
(i,j)为右下角的最大没有
0
0
0的矩阵。
如果这个矩阵想要扩大,就需要顾及到他左方,左上方,上方的矩阵的感受,要不然他是无法扩大的。如下图:
所以可以理所当然的推出动态转移方程:
对
于
每
一
个
1
≤
i
≤
n
,
1
≤
j
≤
m
,
有
:
f
i
,
j
=
{
0
a
i
,
j
=
0
m
i
n
(
f
i
−
1
,
j
,
f
i
,
j
−
1
,
f
i
−
1
,
j
−
1
)
+
1
a
i
,
j
=
1
对于每一个1\le i\le n,1\le j\le m,有: \\ f_{i,j}=\begin{cases} 0&a_{i,j}=0 \\ min(f_{i-1,j},f_{i,j-1},f_{i-1,j-1})+1&a_{i,j}=1 \end{cases}
对于每一个1≤i≤n,1≤j≤m,有:fi,j={0min(fi−1,j,fi,j−1,fi−1,j−1)+1ai,j=0ai,j=1
最后不要忘了取其中的最大值!
最后,祝大家早日
上代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m,x,maxx=0;
cin>>n>>m;
int dp[101][101];
memset(dp,0,sizeof(dp));
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
cin>>x;
if(x==0) continue;
else
{
dp[i][j]=min(dp[i-1][j],min(dp[i][j-1],dp[i-1][j-1]))+1;
}
maxx=max(maxx,dp[i][j]);
}
}
cout<<maxx<<endl;
return 0;
}
完美切题 ∼ \sim ∼