1051 最大子矩阵和

  1. 2 秒
  2. 131,072 KB
  3. 40 分
  4. 基础题
  5. 4 级题
  6. 难题

一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值。例如:3*3的矩阵:-1 3 -12 -1 3-3 1 2和最大的子矩阵是:3 -1-1 31 2

一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值。

例如:3*3的矩阵:

 

-1 3 -1

2 -1 3

-3 1 2

 

和最大的子矩阵是:

 

3 -1

-1 3

1 2

收起展开全文

输入

第1行:M和N,中间用空格隔开(2 <= M,N <= 500)。
第2 - N + 1行:矩阵中的元素,每行M个数,中间用空格隔开。(-10^9 <= M[i] <= 10^9)

输出

输出和的最大值。如果所有数都是负数,就输出0。

输入样例

3 3
-1 3 -1
2 -1 3
-3 1 2

输出样例

7

 解题思路

对测试用例来说,假设最大的子矩阵的行数为3,那么就可以把列数相加,二维矩阵也就变成了一维矩阵 ,题目就转换成了求最大子段的和。那么只要遍历假设的部分,也就是遍历行数,就能求出最大的子矩阵行数为1,行数为2的最大子段和,找出最大的值就是二维矩阵的最大子矩阵的值。时间复杂度为O(n^3).

AC代码 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int map[510][510];
long long a[510];
int main()
{
int m,n,i,j,k;
cin>>m>>n;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
cin>>map[i][j];
long long ans=0;
for(i=0;i<n;i++)
{
memset(a,0,sizeof(a));
for(j=i;j<n;j++)
{
for(k=0;k<m;k++)
a[k]=(i==j?map[i][k]:(a[k]+map[j][k]));
long long sum=0;
for(k=0;k<m;k++)
{
sum=(sum+a[k]>0)?sum+a[k]:0;
ans=(sum>ans)?sum:ans;
}
}
}
printf("%lld\n",ans);
return 0;
}