P2331 SCOI2005 最大子矩陣

2022-06-21 11:12:14 字數 1065 閱讀 3052

這裡有乙個n*m的矩陣,請你選出其中k個子矩陣,使得這個k個子矩陣分值之和最大。注意:選出的k個子矩陣不能相互重疊。

其中\(1\le n\le 100,1\le m\le 2,1\le k\le 10.\)

\(m\)只有\(1\)和\(2\)兩種取值,所以直接討論就好

\(m=1\)時:

是前\(k\)個最大連續欄位和

定義\(f[i][j]\)為前\(i\)個數中取出\(j\)個矩形的最大和

則有:\[\begin

&選:f[i][j]=max(f[k-1][j-1]+s[i]-s[k-1])\\

&不選:f[i][j]=max(f[i][j],f[i-1][j])

\end

\]\(m=2\)時:

定義\(f[i][j][p]\)為第一列選到第\(i\)個數,第二列選到第\(j\)個數時,總共\(k\)個子矩陣的最大和

則有:\[\begin

&不選:f[i][j][p]=max(f[i-1][j][p],f[i][j-1][p])\\

&選第一列:f[i][j][p]=max(f[k-1][j][p-1]+s1[i]-s1[k-1])\\

&選第二列:f[i][j][p]=max(f[i][k-1][p-1]+s2[j]-s2[k-1])\\

&選兩列:if(i==j) f[i][j][p]=max(f[k-1][k-1][p-1]+s1[i]+s2[i]-s1[k-1]-s2[k-1])

\end

\]注意\(k\)的邊界

#includeusing namespace std;

const int n =110;

int n,m,k,s1[n],s2[n],f[n][n][n];

int main() }

if(m==1)

} printf("%d\n",f[n][k][0]);

}else

}}

printf("%d\n",f[n][n][k]);

} return 0;

}

P2331 SCOI2005 最大子矩陣

傳送門 首先感謝ccsc友 xi 好 zhi 的講解 康康m的範圍 m只能取1或者2 先看m 1 是一條鏈 那麼對於第i個點有三種情況 1 和上面連在一起成乙個矩陣 2 和下面連在一起成乙個矩陣 3 成為斷點 同樣的 對於m 2我們也這樣分析 設f i j k 代表第i行取了j個矩陣屬於第k種情況 ...

洛谷 P2331 SCOI2005 最大子矩陣

這裡有乙個n m的矩陣,請你選出其中k個子矩陣,使得這個k個子矩陣分值之和最大。注意 選出的k個子矩陣不能相互重疊。輸入格式 第一行為n,m,k 1 n 100,1 m 2,1 k 10 接下來n行描述矩陣每行中的每個元素的分值 每個元素的分值的絕對值不超過32767 輸出格式 只有一行為k個子矩陣...

洛谷P2331 SCOI2005 最大子矩陣

題目 dp此題可以分為兩個子問題。m 等於 1 原題目轉化為求一行數列裡的 k 塊區間的和,區間可以為空的值。直接定義狀態 dp i t 表示前i個數分為t塊的最大值。因為區間可以為空,所以最大值再小也不會比0小,所以初始化 dp 值為 0 有方程 dp i t max dp i 1 t dp j ...