最大子矩阵和

最大子矩阵和

问题描述
  给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。
  其中,A的子矩阵指在A中行和列均连续的一块。
输入格式
  输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。
  接下来n行,每行m个整数,表示矩阵A。
输出格式
  输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。
样例输入
3 3
-1 -4 3
3 4 -1
-5 -2 8
样例输出
10

思路:

最大子矩阵和问题可以类比于最大字段和问题,从一维变成二维,dp思路,在输入的时候做一个处理,让a[i,j]变为存放前i行j列的和,降低复杂度。状态转移方程为sum[k+1]=sum[k]<0?0:sum[k]+a[i,j];表示第k行i到j的和。因为a[i,j]为存放前i行j列的和,所以a[i,j]=a[k,j]-a[k,i-1];
-1 -4 3
3 4 -1
-5 -2 8
存进a[i,j]后
-1 -5 -2
3 7 6
-5 -7 1

代码:

#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
int a[505][505];
int n,m;
int main()
{
    int d,maxx=-0x3f3f3f3f;
    scanf("%d%d",&n,&m);
    memset(a,0,sizeof(a));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&d);
            a[i][j]=a[i][j-1]+d;   //第i行前j个元素和
        }
     for(int i=1;i<=n;i++)        //第k行第i到j个元素和
        for(int j=i;j<=m;j++)
     {
         int sum=0;
         for(int k=1;k<=n;k++)
         {
             if(sum<0) sum=0;          //当sum<0,在加上下一个值会负增长,因此让sum等于0
             sum+=a[k][j]-a[k][i-1];
            if(maxx<sum)
                maxx=sum;
         }
     }
     printf("%d\n",maxx);
     return 0;
}

猜你喜欢

转载自blog.csdn.net/lhhnb/article/details/79645314