描述 给定一个由整数组成二维矩阵(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

第一,如何更简单地计算出一个子矩阵的和?

先考虑子问题行数固定的矩阵(i=2,j=4)k=1~4里的矩阵哪个累加和最大,把所有的列相加得到一个一维数据,求一维数据的最大累加和。在数据录入的时候,就应该是num[i]+=num[i-1],这样,要计算从j到i的数据之和,直接num[i]-num[j-1]就能直接得出了

第二,如何求数组的最大累加和

tempmax表示当前数组以i结尾的子串的最大累加和,如果tempmax<0。说明0~i的任何一段都不可能是最大累积和的子序列。此时令tempmax=0要重新计算累加和

第三,如何遍历出所有可能的子矩阵?

这里可以使用三个变量i,j,k来遍历。如果一个矩阵大小是M*N的,那么可以使i从0到M,再使j从每一个i到M,这样就把行方向给遍历完了。再考虑列方向,直接在每一种i,j组合下,进行0到N的遍历,那么这样就等于是把所有子矩阵的情形给遍历完了。

LeetCode085子矩阵最大累加和(相关话题:动态规划)_动态规划

代码如下:
 


public class 最大子矩阵 {

	private static int num[][] = new int[101][101];
	private static int n;
	private static Scanner input = new Scanner(System.in);

	public static void main(String[] args) {
		getMax();
	}
	public static int getMax() {

		n = input.nextInt();
		n = n - 1;
		while (n  >= 0) {
			int r, c;
			r = input.nextInt();
			c = input.nextInt();
			int i, j, k;
			initArr(r,c,num);
			for (i = 1; i <= r; i++)
				for (j = 1; j <= c; j++) {
					num[i][j] = input.nextInt();
					num[i][j] += num[i - 1][j];
				}
			int temp = 0;
			int max = num[1][1];
			int tempmax;
			for (i = 1; i <= r; i++) {
				for (j = i; j <= r; j++) {
					tempmax = 0;
					for (k = 1; k <= c; k++) {
						temp = num[j][k] - num[i - 1][k];
						tempmax = (tempmax >= 0 ? tempmax : 0) + temp;
						max = tempmax > max ? tempmax : max;
					}
				}
			}
			System.out.println(max);
		}
		return 0;
	}

	public static  void initArr(int r, int c, int[][] a) {
		for (int i = 0; i < r; i++) {
			for (int j = 0; j < c; j++) {
				a[i][j] = 0;
			}
		}
	}

}