给你一个 m * n 的矩阵,矩阵中的元素不是 0 就是 1,请你统计并返回其中完全由 1 组成的 正方形 子矩阵的个数。
示例:
 
💡
一个暴力的想法是,枚举正方形的右下角, 统计有多少个右下角在(i,j)的全1正方形。 比如计算右下角在(4,4)的全1正方形的个数,可以先算出右下角在(4,4)的全1正方形的最大边长。 在下图中,最大边长等于4,那么内部的边长为3,2,1的正方形也全为1。 所以右下角在(4,4)的全1正方形个数等于4,这等于最大边长。 于是问题转换成,计算右下角在(i,j)的全1正方形的最大边长。
notion image
 
为方便描述,设右下角在(i,j)的全1正方形的最大边长为。 在算的时候我们遍历了图中3x3正方形的所有1。 在算的时候我们遍历了图中4×4正方形的所有1。 这个过程存在重复遍历,浪费时间,考虑用动态规划解决。
notion image
 
注意对应的正方形(除去右下角)可以被对应的正方形的并集覆盖。 (这个想法和二维前缀和的想法类似) 最终等于多少,取决于, 三者的大小。
notion image
可得状态转移方程:
 
然而,当 i=0 或者 j=0 时,上式会产生负数下标 −1。
为避免出现负数下标,可以在 f 矩阵的最上边添加一行 0,最左边添加一列 0,对应下标出界的状态(正方形的最大边长为0),故状态转移方程变为:
 
最终答案为整个矩阵的元素和。
 
Loading...