一、題目
一個M*N的矩陣,找到此矩陣的一個子矩陣,並且這個子矩陣的元素的和是最大的,輸出這個最大的值。
二、解題思路
這題是最大子段和的二維推廣,實質可以將二維進行枚舉,並化爲最大子段和求解。最後子矩陣一定是在某兩行之間的。因此假設
我們認爲子矩陣在第i行和第j行之間,我們如何得到i和j呢,可以進行枚舉。 枚舉所有1<=i<=j<=M,表示最終子矩陣選取的行範圍。
然後對每一種i,j行間選定後對列用最大子段和處理(可以想象成將矩陣的 i 行到 j 行進行壓縮成一行後對這一行進行最大字段和求解)。
三、代碼
#include <iostream>
using namespace std;
int main (){
int m, n; // m行n列
cin>>m>>n;
int a[m+1][n+1];
int t;
for(int i = 1; i<=n; i++) a[0][i] = 0; // 第0行填0
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++){
cin>>t;
a[i][j] = a[i-1][j] + t;
}
int b[n+1]; // 記錄每一輪的最大子段和
int Max = a[1][1]; // 記錄最大子矩陣和
for(int i=1; i<=m; i++){
for(int j=i; j<=m; j++){
b[1] = a[j][1] - a[i-1][1]; // 第一個數複製
Max = max(Max, b[1]);
for(int k=2; k<=n; k++){
b[k] = max(b[k-1] + a[j][k] - a[i-1][k], a[j][k] - a[i-1][k]); // 每一輪的最大子段和算法
if(b[k] > Max) Max = b[k]; // 更新總的最大子矩陣和
}
}
}
cout<<Max<<endl;
return 0;
}