描述
给定一个由整数组成二维矩阵(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
//题解:和求一维数列的连续最大子序列的和类似。这题是求二维的最大子矩阵的和,我们只要把二位的矩阵压缩成一维的数列,
就可以用根据求最大子序列的和的方法,来解这题。
//标程:
#include <cstdio> #include <cstring> #include <iostream> using namespace std; int dp[101][101]; inline int max(int x,int y) { return x > y ? x : y; } int main() { // freopen("a.txt","r",stdin); int i, j, k, ans, t; int n, m, Max, temp; scanf("%d",&t); while(t--) { memset(dp,0,sizeof(dp)); scanf("%d%d",&n,&m); for(i = 1; i <= n; i ++) { for(j = 0; j < m; j ++) { scanf("%d",&dp[i][j]); dp[i][j] = dp[i][j] + dp[i-1][j]; } } ans = dp[1][0]; for(i = 1; i <= n; i ++) for(j = i; j <= n; j ++) { Max = 0; for(k = 0; k < m; k ++) { temp = dp[j][k] - dp[i-1][k]; //以列为单位,向右平移,得到矩阵; Max = (Max >= 0 ? Max : 0) + temp; /*求矩阵和。如果当前的矩阵和小于0,则从下一列重新开始。*/ ans = max(Max, ans); } } printf("%d\n",ans); } }