描述
给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最大,并把这个子矩阵称为最大子矩阵。
例子:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
其最大子矩阵为:
9 2
-4 1
-1 8
其元素总和为15。
- 输入
- 第一行输入一个整数n(0<n<=100),表示有n组测试数据;
每组测试数据:
第一行有两个的整数r,c(0<r,c<=100),r、c分别代表矩阵的行和列;
随后有r行,每行有c个整数; - 输出
- 输出矩阵的最大子矩阵的元素之和。
- 样例输入
-
1 4 4 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2
- 样例输出
-
15
解题思路:联想到数组的最大子和问题。我们可以把一个矩阵M*N看成是N位数组,每一列看成是一个数字。即转化成求N个连续数字的最大子和问题了。1 //矩阵的最大子和,程序一定要考虑都位负的情况 2 #include "stdafx.h" 3 #include <iostream> 4 int maxSubSum(int m,int n); 5 int maxSum(int k,int b[]); 6 using namespace std; 7 int M[100+1][100+1],b[100+1]; 8 int _tmain(int argc, _TCHAR* argv[]) 9 { 10 int m,n,x; 11 cin>>x; 12 while(x--){ 13 cin>>m>>n; 14 for(int i=1;i<=m;i++) 15 for(int j=1;j<=n;j++) 16 cin>>M[i][j]; 17 cout<<maxSubSum(m,n)<<endl; 18 } 19 return 0; 20 } 21 int maxSubSum(int m,int n){ 22 int sum=M[1][1]; 23 int max=M[1][1]; 24 for(int i=1;i<=m;i++){ 25 for(int k=1;k<=n;k++)b[k]=0; 26 for(int j=i;j>=1;j--){ 27 for(int k=1;k<=n;k++) 28 b[k]+=M[j][k]; 29 sum=maxSum(n,b); 30 if(sum>max) 31 max=sum; 32 } 33 } 34 return max; 35 } 36 int maxSum(int k,int b[]){ 37 int sum = b[1],count=0; 38 for (int i = 1; i <= k; i++) { 39 if (count > 0) 40 count += b[i]; 41 else 42 count=b[i]; 43 if (count > sum) 44 sum = count; 45 } 46 return sum; 47 }