Largest Square
Posted 佐鼬Jun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Largest Square相关的知识,希望对你有一定的参考价值。
Largest Square
题目链接: link.
Given a matrix (H × W) which contains only 1 and 0, find the area of the largest square matrix which only contains 0s.
Input
H W
c1,1 c1,2 … c1,W
c2,1 c2,2 … c2,W
:
cH,1 cH,2 … cH,W
In the first line, two integers H and W separated by a space character are given. In the following H lines, ci,j, elements of the H × W matrix, are given.
Output
Print the area (the number of 0s) of the largest square.
Constraints
1 ≤ H, W ≤ 1,400
Sample Input
4 5
0 0 1 0 0
1 0 0 0 0
0 0 0 1 0
0 0 0 1 0
Sample Output
4
题意: 给一个H×W个边长为1的正方形瓷砖排列在一起,0代表瓷砖干净,1代表瓷砖有污渍,输出仅有干净瓷砖构成的最大正方形的面积。
思路: 用dp(i,j)来表示从瓷砖(i,j)向左上方扩展可形成的最大正方形的边长(瓷砖数),那么要知道dp(i,j)就要知道dp(i-1,j)、dp(i,j-1)和dp(i-1,j-1)三个值,也就是左上方、上方、左侧的最大正方形的值。
因为dp[i][j]以右下角向左上角扩展形成最大正方形,能向外拓展的最大长度,取决于那条边最先碰到1(有污渍的瓷砖),而这就需要dp(i-1,j)、dp(i,j-1)和dp(i-1,j-1)算出来的值,来取最小值,最小值,代表最先碰到有污渍的瓷砖,一碰有污渍的瓷砖就无法再往外拓展了。
当前dp[i][j]如果是有污渍的瓷砖,就无法形成正方形,直接赋值为0即可。
(明明是找最大正方形,方程确实最小值,着实有点反直觉 )
综上所述,动态转移方程就是:
d
p
[
i
]
[
j
]
=
m
i
n
(
d
p
[
i
−
1
]
[
j
−
1
]
,
m
i
n
(
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
]
[
j
−
1
]
)
)
+
1
dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1
dp[i][j]=min(dp[i−1][j−1],min(dp[i−1][j],dp[i][j−1]))+1
//动态转移的核心
for(int i=1;i<H;i++) {
for(int j=1;j<W;j++) {
if(g[i][j]==1) {
dp[i][j]=0;
}
else {
dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1;
res=max(res,dp[i][j]); //找最大边长(最大面积)
}
}
}
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 1411;
int dp[N][N], g[N][N];
int solve(int H, int W) {
int res = 0;
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
dp[i][j] = (g[i][j] + 1) % 2;
res |= dp[i][j];
}
}
for (int i = 1; i < H; i++) {
for (int j = 1; j < W; j++) {
if (g[i][j] == 1) {
dp[i][j] = 0;
} else {
dp[i][j] =
min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1;
res = max(res, dp[i][j]);
}
}
}
return res * res;
}
int main() {
int H, W;
scanf("%d%d", &H, &W);
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
scanf("%d", &g[i][j]);
}
}
printf("%d\\n", solve(H, W));
return 0;
}
To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激
以上是关于Largest Square的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode 1895. Largest Magic Square
[LeetCode] 1139. Largest 1-Bordered Square 最大的以1为边界的正方形
leetcode_1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold_[二维前缀和](代码片段