這裡有乙個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 ...