下文中假定有草莓的格子为 $1$,没有草莓的格子为 $0$。原题中 $H,W$ 为下文的 $n,m$。
先给出一个结论,一个矩阵是合法的充要条件是存在一个切割点使得左上角(非空)全是 $1$,右下角(可空)全是 $0$,并且左下角,右上角均为合法矩阵。
充分性是显然的,首先左上角和右下角一定合法,而左下角,右上角所有标记元组的体现均为两维加一个 $tag$ 的形式,必定不会有冲突。
接下来考虑证明必要性:
考虑删除了全 $0$ 行和全 $0$ 列一定不劣,因此我们先删除所有的全 $0$ 行和全 $0$ 列。
考虑 $l_i$ 表示前 $i$ 行最靠左的 $0$ 的下标 $- 1$(默认下标从 $1$ 开始)。
结论 1:第一行所有 $1$ 都在 $0$ 的左边。
考虑反证法,找到第一个 $0$ 的位置,假设是 $(1,y)$,那么找到第 $y$ 列中第一个 $1$,设其坐标为 $(x,y)$。如果 $(x,y)$ 的左边有不超过 $y - 2$ 个 $1$,那么其 $y$ 的标号就一定 $\le y - 1$,与第一行所冲突;否则,如果 $(x,y)$ 的左边有 $y - 1$ 个 $1$,则 $(1,y)$ 右边的第一个 $1$ 与其标号冲突。与假设矛盾,得证。
若有 $a_n > 0$,则我们可以直接删去第一列,不影响其结果,直到有 $a_n = 0$ 为止。
我们考虑此时找到最小的 $i$ 满足 $l_i < l_{i-1}$,且这一行存在一个 $0$ 在 $1$ 左边,则 $(i-1,l_{i-1})$ 为一个合法切分点(作为左上区域的右下角)。以下我们对于这个结论进行证明:
引理 1:$(i,[l_{i-1} + 1,m])$ 全都为 0。
反证法,假设 $(i,[l_{i-1} + 1,m])$ 存在 $1$。
引理 2:因为有 $(i,l_i + 1)$ 是 $0$,又有 $l_i < l_{i-1}$,因此 $(i,[1,l_{i-1}])$ 的 $1$ 数量一定 $< l_{i-1}$。
找到第 $i$ 行中在 $[l_{i-1} + 1,m]$ 列之间的最左边的 $1$,记其坐标为 $(i,j)$,则 $([1,i-1],j)$ 一定有至少一个 $0$,否则你考虑最小的 $k$ 满足 $l_k = l_{i-1}$,则 $(k,l_k)$ 也为最小切分点,与 $i$ 的最小性矛盾。与假设矛盾,得证。(或者你根据引理 2 也可以知道 $(i,j)$ 和左上角格子标号冲突了,也能证)
引理 3:$([i+1,n],[l_{i-1} + 1,m])$ 全都为 0。
根据引理 1,同样可以证出 $([i+1,n],l_{i} + 1)$ 全都为 $0$,在此不再赘述。
所以从第 $i + 1$ 行开始,每一行中前 $l_{i-1}$ 个数一定有至少一个数为 $0$。
然后我们考虑整个右下角,若有 $(x,y)$ 为 $1$,则其左边的 $1$ 一定有 $< l_{i-1}$ 个,上面的 $1$ 一定有 $< i - 1$ 个,因此其标号一定与左上角中的一个格子的标号冲突,与假设矛盾,得证。
那么结合引理 1 和引理 3,我们就证明完了这个结论。
那么有了这个结论我们就可以考虑 dp 了,设 $f_{i,j}$ 表示使得子矩形 $([i,n],[j,m])$ 变为合法的最小操作次数是多少,那么我们枚举切割点 $(x,y)$ 进行转移即可做到 $O(n^4)$。
考虑到这么一个事情,我们在枚举切割点 $(x,y)$ 的时候,在 $x$ 相同时,选取最小的 $y$ 一定不劣,因为你考虑到选取更大的 $y$ 相当于强制更大的左上角全赋值为 $1$,一定不优,因此直接双指针 $y$ 即可,复杂度变为 $O(n^3)$。
ll n,m;
ll a[310][310];
ll sum[310][310];
ll X[310][310],Y[310][310];
ll R;
ll query(ll x,ll y,ll xx,ll yy){
if(x>xx || y>yy) return 0;
return sum[xx][yy]-sum[x-1][yy]-sum[xx][y-1]+sum[x-1][y-1];
}
ll f[310][310];
void solve(){
cin>>n>>m;
forl(i,1,n) forl(j,1,m) cin>>a[i][j],sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
forl(i,1,n) forl(j,1,m) f[i][j]=(n-i+1)*(m-j+1);
forr(i,n,1) forr(j,m,1){
X[i][j]=X[i+1][j],Y[i][j]=Y[i][j+1];
if(!query(i,j,n,j)) Min(f[i][j],f[i][j+1]),Y[i][j]++;
if(!query(i,j,i,m)) Min(f[i][j],f[i+1][j]),X[i][j]++;
R=j;
forr(x,n,i){
while(R<m && query(x+1,R+1,n,m)) R++;
ll y=R;
if(!query(x+1,y+1,n,m)) Min(f[i][j],f[i][y+1]+f[x+1][j]+(x-i+1-X[i][j]+X[x+1][j])*(y-j+1-Y[i][j]+Y[i][y+1])-query(i,j,x,y));
}
}
cout<<f[1][1]<<endl;
}