洛谷P2331 SCOI2005 最大子矩陣

2022-03-17 15:29:29 字數 1109 閱讀 4929

題目

dp此題可以分為兩個子問題。

\(m\)等於\(1\):

原題目轉化為求一行數列裡的\(k\)塊區間的和,區間可以為空的值。

直接定義狀態\(dp[i][t]\)表示前i個數分為t塊的最大值。

因為區間可以為空,所以最大值再小也不會比0小,所以初始化\(dp\)值為\(0\)。

有方程\(dp[i][t]=max(dp[i-1][t],dp[j][t-1]+\sum_^a[k])\)

考慮順序及邊界,發現此時的\(dp[i][t]\)是從\(t-1\)塊轉移過來的,所以\(j\)要和\(i\)斷開。但是又因為可以從\(1\)一路取到\(i\),因此\(j+1\)可以取到\(1\)。所以\(0<=j,而且\(t\)要放在迴圈的最外面。

\(m\)等於\(2\):

同樣可以\(dp\),定義狀態\(dp[i][j][t]\)為第一列取到\(i\),第二列取到\(j\),分為\(t\)塊的最大值。

有方程\(dp[i][j][t]=max(dp[i-1][j][t],dp[i][j-1][t],dp[o][j][t-1]+\sum_^a[k][1],dp[i][o][t-1]+\sum_^a[k][2]);\)

如果i等於j的話,還有方程

\(dp[i][j][t]=max(dp[i][j][t],dp[o][o][t-1]+\sum_^ia[k][1]+a[k][2]);\)

順序及邊界和第一問一樣。

#include #define n 1001

using namespace std;

int n, m, k, maxn;

int dp[n][n][40], a[n][n], sum1[n], sum2[n], dp1[n][40];

int max(int a, int b, int c, int d)

int q1(int i, int j)

int q2(int i, int j)

int main()

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

} else

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

} return 0;

}

洛谷 P2331 SCOI2005 最大子矩陣

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

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