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

题目:从m*n矩阵中找出元素和最大的子矩阵。

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

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

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

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

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

 1 #include <iostream.h>
 2 int maxSubArray(int n,int a[])
 3 {
 4     int b=0,sum=-10000000;
 5     for(int i=0;i<n;i++)
 6     {
 7         if(b>0) b+=a[i];
 8         else b=a[i];
 9         if(b>sum) sum=b;
10     }
11     return sum;  
12 }
13 int maxSub(int n,int array[][10])
14 {
15     int i,j,k,max=0,sum=-100000000;
16     int b[10];
17     for(i=0;i<n;i++)
18     {
19        for(k=0;k<n;k++)//初始化b[]
20        {
21            b[k]=0;
22        }
23        for(j=i;j<n;j++)//把第i行到第j行相加,对每一次相加求出最大值
24        {
25             for(k=0;k<n;k++)
26             {
27                 b[k]+=array[j][k];
28             }
29             max=maxSubArray(k,b);  
30             if(max>sum)
31             {
32                sum=max;
33             }
34        }
35      }
36      return sum;
37 }
38 void main()
39 {
40     int n,array[10][10];
41     cout<<"输入矩阵行列数";
42     cin>>n;
43     cout<<"
输入矩阵"<<endl;   
44     for(int i=0;i<n;i++)
45     {
46         for(int j=0;j<n;j++)
47         {
48             cin>>array[i][j];
49         }
50     }
51     cout<<"子矩阵元素和最大为"<<maxSub(n,array)<<endl;
52 }

原文地址:https://www.cnblogs.com/candy-yyn/p/3627067.html