1. 程式人生 > 其它 >P2331 [SCOI2005]最大子矩陣 題解

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