bzoj 1084 最大子矩陣

2022-04-08 00:40:52 字數 1256 閱讀 3353

written with stackedit.

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

ps:這裡的題意有些不明確...可以選空矩陣(最多選\(k\)個),不能重疊指的是不能有相交部分.

第一行為\(n,m,k\)(\(1≤n≤100,1≤m≤2,1≤k≤10\)),接下來\(n\)行描述矩陣每行中的每個元素的分值(分值的絕對值不超過\(32767\))。

只有一行,為\(k\)個子矩陣分值之和最大為多少。

3 2 2

1 -3

2 3-2 3

none.

對於\(m=2\)的情況,與\(m=1\)類似,用\(f[i][j][k]\)表示考慮前\(i\)個數,用了\(j\)個矩形,而\(k\)用於表示第\(i\)行的選擇情況.

不妨令\(k=0\)表示這一行都沒選.

\(k=1\)表示這一行只選了左邊的數.

\(k=2\)表示這一行只選了右邊的數.

對於左右兩個數都選的情況,注意到樣例中第二行的\(2,3\)雖然同時被選到,但屬於不同的子矩形,所以要對是否在同乙個子矩形中進行區分.

\(k=3\)表示這一行同時選了左右兩個數,且兩個數屬於相同的子矩形

\(k=4\)表示這一行同時選了左右兩個數,且兩個數屬於不同的子矩形.

在轉移時分別判斷能否和上一行的各個狀態拼接上,就完成了狀態轉移.

這樣我們也不用特判\(m\)了,將\(m=1\)的時候看做第二列都是\(0\),一起處理.

具體轉移方程和細節參見**.

#includeusing namespace std;

inline int read()

while (jp>='0'&&jp<='9')

return out*fh;

}int n,m,k;

const int maxn=101;

int a[maxn][2];

int f[maxn][11][5];

inline void upd(int &x,int y)

void sub_line()

} printf("%d\n",ans);

}void sub_martix()

} printf("%d\n",ans);

}int main()

bzoj1084 最大子矩陣

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

BZOJ1084 最大子矩陣(動態規劃)

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

BZOJ 1084 最大子矩陣 線性dp

給出乙個n m n mn m的矩陣,其中n 100,m 2 n leq100,m leq2 n 100,m 2,然後求選取k kk個子矩陣的最大值是多少。注意到這個m mm只有1 11和2 22兩種情形。當m 1 m 1m 1的時候,這個問題退化為乙個長度為n nn的序列選k kk段的最大值。fi,...