最大子矩陣是一種典型的dp問題。某種程度上說是最大連續子串行和問題的擴充套件。
這是最常見的最大子矩陣問題的體型。簡單的解決方案就是把列累加,遍歷任意兩行的累加值的差值,然後就轉換成了普通的最大連續子串行和問題。從而將二維問題轉換為一維。時間複雜度較高為o(n^3)
#include#include#includeusing namespace std;
const int max=104;
int a[max][max];
int dp[max];
int main()
}int max_sum=0;
for(int i=1; i<=n; i++)}}
printf("%d\n",max_sum);
}}
在輸入矩陣值的時候做了處理,a[i][j]+=a[i-1][j]使得a矩陣中a[i][k]儲存的是原矩陣中第k列元素,從上累加到第i個元素的和。
所以下面的dp[k]=a[i][k]-a[j][k],dp[k]表示的就是原矩陣第k列中,第i行到第j行的元素和。
三層for迴圈,前兩層迴圈為遍歷任意兩行的差值。也就是說遍歷子矩陣的首行和尾行的所有情況。
內部第三層for迴圈,就是一般的求解一維最大連續子串行和的求法。
這道題與上題不同,它加了兩個限制條件,就是子矩陣的兩個維度必須是給定的x,y值。
#include#include#includeusing namespace std;
const int max=1004;
int a[max][max];
int dp[max];
int main()
}int max_sum=0;
for(int i=x; i<=m; i++)}}
printf("%d\n",max_sum);
}}
大同小異,關鍵在於決策之時。dp[j]-dp[j-y]表示原矩陣中以(i,j)為右下角元素,行數為x,列數為y的子矩陣和。 bzoj1084 SCOI2005 最大子矩陣
description 這裡有乙個n m的矩陣,請你選出其中k個子矩陣,使得這個k個子矩陣分值之和最大。注意 選出的k個子矩陣 不能相互重疊。input 第一行為n,m,k 1 n 100,1 m 2,1 k 10 接下來n行描述矩陣每行中的每個元素的分值 每個元素的 分值的絕對值不超過32767 ...
BZOJ1084 SCOI2005 最大子矩陣
portal 注意到m只能為1或2 分類討論。m 1的時候其實就是最大k段連續子段和。f i j ma x f i j ma x f k j f k j 1 sum i s um k m 2時 g i j k 表示第一列到i,第二列到j,選了k個子矩陣的最大和 那麼有一下幾種情況 都不選 g i j...
BZOJ1084 SCOI2005 最大子矩陣
這題顯然是dp。定義f i j k 表示前i行j列裡有k個矩陣的最大元素總和。因為m 2,所以可以分兩種情況分別寫乙個dp,套一套容斥就行了。如下 include include include using namespace std const int maxn 105,maxk 15 int n...