最大子矩阵和

一、题目

一个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;
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章