最大子矩阵的和
***定义:***就是不限定子矩阵的行和列,只要求和最大。
例如a[3][3]=
1 2 3
0 7 -1
1 -2 0
的max=a[0][0]+a[0][1]+a[0][2]+a[1][0]+a[1][1]+a[1][2]=12;
***基本思路:***假设最大子矩阵的行数为i,(i从1到n),分别求出1-i,2-(i+1),3-(i+2),…(n-i+1)-(n)行所对应列的和,对所得结果的每一个数组求最大子段和,这些和中的最大值就是最大子矩阵之和。
举例:
a[3][3]=
1 2 3
0 7 -1
1 -2 0
假设最大子矩阵为1行,i=1,则不需要计算对应列的和,直接就a[0][],a[1][],a[2][]的最大字段和,分别为6,7,1,此时max=7;i=2,即最大子矩阵为2行,分别求出1-i,2-(i+1),3-(i+2),…(n-i+1)-(n)行所对应列的和,第1行+第2行=(1,9,2),第2行+第3行=(1,5,-1),在求所得一维矩阵的最大子段和分别为12和6,此时更新max=12;i=3,即最大子矩阵为3行,此时第1行+第2行+第3行=(2,7,2),该数组的最大字段和为11,此时max不更新,仍为12.
代码
#include
using namespace std;
#define m 3
#define n 3
//求一维数字最大子段和函数
int linemaxsum(int a[],int y)
{
int sum=0;
int b=0;
for(int i=0;i<y;i++)
{
if(b>0) b+=a[i];
else
b=a[i];
if(b>sum) sum=b;
}
return sum;
}
//求二维数组最大子矩阵函数
int matrixmax(int a[n][m])
{
int b[n][m];//b存储的是前i行的和
int maxl=0,result[m],maxll;//其中maxll存放当前计算的矩阵的和,maxl存放当前最大 子矩阵和,resul数组存放i-j行到j行对应各列的和
for(int j=0;j<m;j++)
{
b[0][j]=a[0][j];
}
for(int i=1;i<n;i++)
{
for(int j=0;j<m;j++)
{
b[i][j]=b[i-1][j]+a[i][j];
}
}
for(int i=1;i<=n;i++)//假设最大子矩阵为i行
{
for(int j=i-1;j<n;j++)//数组从上向下求和,共有几个需要求最大子段的数组
{
if(j-i<0)//如果是计算时包括第一行,则直接赋值
{
for(int k=0;k<m;k++)
{
result[k]=b[j][k];
}
}
else
{
for(int k=0;k<m;k++)
{
result[k]=b[j][k]-b[j-i][k];//计算第j-i行开始到j共i行的和
}
}
maxll=linemaxsum(result,m);//计算每一个新数组的最大字段和
if(maxll>maxl)//并对最大矩阵和进行更新
{
maxl=maxll;
}
}
}
return maxl;
}
int main()
{
int max;
int a[n][m]={{1,2,3},{0,7,-1},{1,-2,0}};
cout<<“a[n][m]=”<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
max=matrixmax(a);
cout<<“max=”<<max;
}
运行结果