最大和
时间限制: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
- 来源
- [苗栋栋]原创
- 上传者
- 苗栋栋
-
解题:很难又很简单的一道题。难在于化二维平面为一维区间这种巧妙的处理方法,容易在于求最大子段和。实质就是暴力+dp
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <climits> 5 using namespace std; 6 int main() { 7 int table[110][110],i,j,ks,n,m,k,temp,ans; 8 scanf("%d",&ks); 9 while(ks--) { 10 scanf("%d %d",&n,&m); 11 memset(table,0,sizeof(table)); 12 for(i = 1; i <= n; i++) 13 for(j = 0; j < m; j++) { 14 scanf("%d",table[i]+j); 15 table[i][j] += table[i-1][j]; 16 } 17 ans = INT_MIN; 18 for(i = 0; i < n; i++) { 19 for(j = i+1; j <= n; j++) { 20 for(temp = k = 0; k < m; k++) { 21 if(temp >= 0) temp += table[j][k]-table[i][k]; 22 else temp = table[j][k]-table[i][k]; 23 if(temp > ans) ans = temp; 24 } 25 } 26 } 27 printf("%d ",ans); 28 } 29 return 0; 30 }