您的位置:首页 > 其它

软工随堂练 找出和值最大的子矩阵 尹亚男 赵静娜

2014-03-27 17:42 225 查看
题目:从m*n矩阵中找出元素和最大的子矩阵。

分析:此题是可看做节课求和值最大子数组的一种延伸。但如果按之前的枚举法显然太过麻烦,复杂度为O(n^4)。那么有没有更好的方法呢?

我们拿出上一道题做了进一步的商讨。找了一些网上的思路得到了如下方法:

#include <iostream.h>
maxSubarray(int n,int a[])
{
int b=0,sum=-100000;
for(int i=0;i<n;i++)
{
if(b>0) b+=a[i];
else b=a[i];
if(b>sum) sum=b;
}
return sum;
}
int main()
{
int a[]={-1,3,4,-6,5,3,7,-9,10,0};
cout<<maxSubarray(10,a)<<endl;
}


此算法的原理是,按序一个个相加,正数越加越大,每得到一个正数更新一次sum;而负数越加越小,当和值为负时,放弃前面的数,更新b,寻找新一轮的正数最大和b,当大于前面的sum时赋给sum。for循环执行一遍,将最大值在b,sum之间动态传递和更新,时间复杂度O(n),与之前的穷举法相比无疑是一种高效的算法。

那么由此延伸到二维数组中,求矩阵的最大子矩阵和,我们得到如下算法:

#include <iostream.h>
int maxSubArray(int n,int a[])
{
int b=0,sum=-10000000;
for(int i=0;i<n;i++)
{
if(b>0) b+=a[i];
else b=a[i];
if(b>sum) sum=b;
}
return sum;
}
int maxSub(int n,int array[][10])
{
int i,j,k,max=0,sum=-100000000;
int b[10];
for(i=0;i<n;i++)
{
for(k=0;k<n;k++)//初始化b[]
{
b[k]=0;
}
for(j=i;j<n;j++)//把第i行到第j行相加,对每一次相加求出最大值
{
for(k=0;k<n;k++)
{
b[k]+=array[j][k];
}
max=maxSubArray(k,b);
if(max>sum)
{
sum=max;
}
}
}
return sum;
}
void main()
{
int n,array[10][10];
cout<<"输入矩阵行列数";
cin>>n;
cout<<"\n输入矩阵"<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cin>>array[i][j];
}
}
cout<<"子矩阵元素和最大为"<<maxSub(n,array)<<endl;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐