历届试题 最大子阵
问题描述
给定一个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
样例说明
取最后一列,和为10。
数据规模和约定
对于50%的数据,1<=n, m<=50;
对于100%的数据,1<=n, m<=500,A中每个元素的绝对值不超过5000。
思路:求出每一列的前缀和,用于求i层到j层的纵向序列和,再求最大横向子序列和,形成最大子阵和
import java.util.Scanner;
public class Main4 {
static int[][] map;
static int[][] cmap;
static int[] rmap;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
map = new int[n + 1][m + 1];
cmap = new int[n + 1][m + 1];
rmap = new int[m + 1];
int ans = Integer.MIN_VALUE;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
map[i][j] = sc.nextInt();
// 前缀和
cmap[i][j] = cmap[i - 1][j] + map[i][j];
}
}
for (int i = 0; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
for (int k = 1; k <= m; k++) {
// i层到j层的纵向和
rmap[k] = cmap[j][k] - cmap[i][k];
}
// 求横向最大子序列和
for (int k = 1; k <= m; k++) {
if (rmap[k - 1] > 0)
rmap[k] += rmap[k - 1];
if (rmap[k] > ans)
ans = rmap[k];
}
}
}
System.out.println(ans);
}
}