将矩阵竖直方向投影相加,即可转化为一维最大子段和问题。
#include <iostream>
using namespace std;
//int a[3][5]={1,2,0,3,4,2,3,4,5,1,1,1,5,3,0};
int a[4][4]={0,-2,-7,0,9,2,-6,2,-4,1,-4,1,-1,8,0,-2};
int maxSum(int *a, int n, int &begin, int &end)//数组的最大子段和
{
int sum=-1000;
int b=0;
for(int i=0; i<n; i++)
{
if(b<=0)
{
b=a[i];
begin=i;
}
else
b+=a[i];
if(sum<b)
{
sum=b;
end=i;
}
}
return sum;
}
void maxarray(int m, int n)//m,n为二维矩阵的行数和列数
{
int i=0, j=0;
int begin=0, end=0;
int maxbegincol=0, maxendcol=0;
int maxbeginrow=0, maxendrow=0;
int maxsum=-65535;
int *b=new int[n];
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
b[j]=0;
for(j=i; j<m; j++)
{
for(int k=0; k<n; k++)
b[k]+=a[j][k];
int sum=maxSum(b, n, begin, end);//竖直投影后转换为一维数组最大子段和
if(sum > maxsum)
{
maxsum=sum;
maxbegincol=begin+1;
maxendcol=end+1;
maxbeginrow=i+1;
maxendrow=j+1;
}
}
}
cout<<"最大子矩阵为:"<<endl;
cout<<"第"<<maxbeginrow<<"行第"<<maxbegincol<<"列到第"<<maxendrow<<"行第"<<maxendcol<<"列"<<endl;
cout<<"最大子矩阵和为:"<<maxsum<<endl;
}
void main()
{
maxarray(4,5);
}