P2331 [SCOI2005]最大子矩阵 题解

DP 题,好像有点恶心,主要是因为能不能选空矩阵的问题。

有些数据好像是可以选空矩阵的有些又不能选,就很离谱,但是根据原数据来看空矩阵应该是不能选的,我也不知道具体情况()

注意到 \(m=1\) 的情况是经典问题,因此直接跳 \(m=2\)

\(f_{i,j,k}\) 表示第一列做到前 \(i\) 个,第二列做到前 \(j\) 个,总共选了 \(k\) 个子矩阵的结果。

那么考虑对于每一列枚举一个 \(p\) 表示将 \([p,i]/[p,j]\) 作为一个新矩阵转移,然后就是如果 \(i=j\) 那么可以两列一起转移,需要一个列上的前缀和。

转移方程如下:

\[f_{i,j,k}=\max\{f_{i-1,j,k},f_{i,j-1,k}\} \]

\[f_{i,j,k}=\max\{f_{p,j,k-1}+sum1_{i}-sum1_{p} \mid 0 \leq p \leq i\} \]

\[f_{i,j,k}=\max\{f_{i.p,k-1}+sum2_j-sum2_p \mid 0 \leq p \leq j\} \]

\[f_{i,j,k}=\max\{f_{p,p,k-1}+sum1_i-sum1_p+sum2_j-sum2_p \mid 0 \leq p \leq i,i=j\} \]

最后答案是 \(f_{n,n,k}\)

大致注意点就是一个 \(f\) 初始化要是 -INF,另外一个点就是需要先枚举第三维,如果不先枚举第三维就是错误的,具体为啥参照 Floyd 正确性证明。

Code:GitHub CodeBase-of-Plozia P2331 [SCOI2005]最大子矩阵.cpp

posted @ 2022-04-17 18:40  Plozia  阅读(21)  评论(0编辑  收藏  举报