二维矩阵的最大子矩阵和,从i到j行的最大矩阵
当i=j时,即为最大连续子序列和
当i != j时,把从i到j行的所有行元素加起来,得到只有一行的一维数组,转变为求一维数组的最大连续子序列和,即为最大子矩阵和。
注意,用辅助二维矩阵记录原始矩阵从上到下加起来的累加矩阵,求i到j行的一维数组只需要将辅助矩阵进行对行的减法即可。
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN = 100;
int matrix[MAXN][MAXN]; //原始矩阵
int total[MAXN][MAXN]; //辅助矩阵
int arr[MAXN]; //一维数组
int dp[MAXN];
int MaxSubsequence(int n){
int maximum = 0;
for(int i = 0; i < n; i++){
if(i == 0){
dp[i] = arr[i];
}else{
dp[i] = max(arr[i], dp[i-1] + arr[i]);
}
maximum = max(maximum, dp[i]);
}
return maximum;
}
int MaxSubmatrix(int n){
int maximal = 0;
for(int i = 0; i < n; i++){
for(int j = i; j < n; j++){
for(int k = 0; k < n; k++){
if(i == 0){
arr[k] = total[j][k];
}else{
arr[k] = total[j][k] - total[i-1][k];//i到j行的一维数组,只需将辅助矩阵进行对行的减法即可
}
}
int current = MaxSubsequence(n);
maximal = max(maximal, current);
}
}
return maximal;
}
int main(int argc, char** argv) {
int n;
while(scanf("%d", &n) != EOF){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
scanf("%d", &matrix[i][j]);
}
}
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(i == 0){
total[i][j] = matrix[i][j];
}else{
total[i][j] = total[i-1][j] + matrix[i][j]; //辅助矩阵,记录原始矩阵从上到下加起来的累加矩阵
}
}
}
int answer = MaxSubmatrix(n);
printf("%d\n", answer);
}
return 0;
}