子矩阵的最大累加和问题

下面这个问题是数组的最大累加和问题的拓展

题目:

给定一个矩阵matrix,其中的值有正、有负、有0,返回子矩阵的最大累加和。 例如,矩阵matrix为:
-90  48 78
 64 -40 64
-81 -7  66
其中,最大累加和的子矩阵为:
 48 78
-40 64
-7  66
所以返回累加和209。

再例如,matrix为:
-1 -1 -1
-1  2  2
-1 -1 -1
其中最大累加和的子矩阵为:
2  2
所以返回累加和 4。

分析过程

如果穷举所有的子矩阵,由于所有的矩阵是(N*N)*(N*N)级别的,再判断最大值是N*N级别的;最后是N^6级别的。

优化一下,这道题要用到子数组的最大累加和问题,这里是求二维的最大和,我们可以把它降到一维的。
我们把行的维数用穷举法降了,即我们现在只关心一行的连续最大累加和。
比如
1 2 3
4 5 6
7 8 9
矩阵的最大累加矩阵只可能是1行的(3种情况,即第1、2、3行的最大累加行的最大值),2行的(2种情况,1、2行或者3,、4行的最大值),3行的(1种情况,本身).
我们比较这六种情况,求出最大值就行了。
这种算法的时间复杂度是N^3.(穷举的复杂度是N^2,得出一行的最大累加和的复杂度是N)

c/c++代码:

#include <iostream>
using namespace std;
//求一行的子数组最大累加和
int maxSubArray(int a[],int n)
{
    int cur=0,max=-100000000;
     for(int i=0;i<n;i++)
     {
          cur += a[i];
          max = cur>max?cur:max;
          cur = cur<0?0:cur;
     }
    return max;  
}
int maxSubMatrix(int array[][3],int n)
{
            int i,j,k,max=0,sum=-100000000;
            int b[3];
            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(b,k); 
                        if(max>sum)
                        {
                                sum=max;
                        }
                  }
            }
            return sum;
}
int main()
{
    int n=3;
    int array[3][3]={{-1,2,0},{-1,-2,-3},{4,9,6}};
                     
    cout<<"MaxSum: "<<maxSubMatrix(array,n)<<endl;
           
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值