最大和
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
5
-
描述
-
给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最大,并把这个子矩阵称为最大子矩阵。
例子:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
其最大子矩阵为:9 2
-4 1
-1 8
其元素总和为15。-
输入
-
第一行输入一个整数n(0<n<=100),表示有n组测试数据;
每组测试数据:
第一行有两个的整数r,c(0<r,c<=100),r、c分别代表矩阵的行和列;
随后有r行,每行有c个整数;
输出
- 输出矩阵的最大子矩阵的元素之和。 样例输入
-
1 4 4 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2
样例输出
-
15
-
第一行输入一个整数n(0<n<=100),表示有n组测试数据;
分析:思路:二维转一维,那就是我们熟悉的最大字段之和了,当然这里并不是一下就直接整个二维表就转换成一维了, 如果有n行,那么就要枚举1 to n高度,对每个高度同一列之和用数组ans[k]储存,然后就是一维的最大字段和,具体见代码
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF 100000000
const int maxn=100+5;
int a[maxn][maxn];
int b[maxn];
int r,c;
int Max_sum(){
int sum=b[0];
int tmp=0;
for(int i=0;i<c;i++){
tmp+=b[i];
if(sum<tmp)sum=tmp;
if(tmp<0)tmp=0;
}
return sum;
}
int main(){
int n;
scanf("%d",&n);
while(n--){
scanf("%d%d",&r,&c);
for(int i=0;i<r;i++){
for(int j=0;j<c;j++)
scanf("%d",&a[i][j]);
}
int max1=-INF;
for(int i=0;i<r;i++){
memset(b,0,sizeof(b));
int j=i;
while(j<r){
for(int k=0;k<c;k++)
b[k]+=a[j][k];
max1=max(max1,Max_sum());
j++;
}
}
printf("%d\n",max1);
}
return 0;
}